Version 2.9.0-6.0.dev
Merge commit 'eaf46c9ccfd2b8ad147a59df273e71528b855b0c' into dev
diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json
index 35fc3b9..7f75303 100644
--- a/.dart_tool/package_config.json
+++ b/.dart_tool/package_config.json
@@ -11,7 +11,7 @@
"constraint, update this by running tools/generate_package_config.dart."
],
"configVersion": 2,
- "generated": "2020-04-21T17:36:03.446742",
+ "generated": "2020-04-27T16:42:25.459210",
"generator": "tools/generate_package_config.dart",
"packages": [
{
@@ -95,7 +95,7 @@
"name": "boolean_selector",
"rootUri": "../third_party/pkg/boolean_selector",
"packageUri": "lib/",
- "languageVersion": "2.0"
+ "languageVersion": "2.4"
},
{
"name": "build_integration",
@@ -107,7 +107,7 @@
"name": "charcode",
"rootUri": "../third_party/pkg/charcode",
"packageUri": "lib/",
- "languageVersion": "1.0"
+ "languageVersion": "2.0"
},
{
"name": "cli_util",
@@ -119,7 +119,7 @@
"name": "collection",
"rootUri": "../third_party/pkg/collection",
"packageUri": "lib/",
- "languageVersion": "2.0"
+ "languageVersion": "2.3"
},
{
"name": "compiler",
@@ -131,7 +131,7 @@
"name": "convert",
"rootUri": "../third_party/pkg/convert",
"packageUri": "lib/",
- "languageVersion": "1.17"
+ "languageVersion": "2.0"
},
{
"name": "crypto",
@@ -143,7 +143,7 @@
"name": "csslib",
"rootUri": "../third_party/pkg/csslib",
"packageUri": "lib/",
- "languageVersion": "2.1"
+ "languageVersion": "2.2"
},
{
"name": "dart2js_info",
@@ -226,7 +226,7 @@
"name": "fixnum",
"rootUri": "../third_party/pkg/fixnum",
"packageUri": "lib/",
- "languageVersion": "2.0"
+ "languageVersion": "2.1"
},
{
"name": "front_end",
@@ -275,19 +275,19 @@
"name": "glob",
"rootUri": "../third_party/pkg/glob",
"packageUri": "lib/",
- "languageVersion": "1.23"
+ "languageVersion": "2.2"
},
{
"name": "html",
"rootUri": "../third_party/pkg/html",
"packageUri": "lib/",
- "languageVersion": "2.0"
+ "languageVersion": "2.3"
},
{
"name": "http",
"rootUri": "../third_party/pkg/http",
"packageUri": "lib/",
- "languageVersion": "2.0"
+ "languageVersion": "2.4"
},
{
"name": "http_io",
@@ -347,7 +347,7 @@
"name": "json_rpc_2",
"rootUri": "../third_party/pkg/json_rpc_2",
"packageUri": "lib/",
- "languageVersion": "2.0"
+ "languageVersion": "2.2"
},
{
"name": "kernel",
@@ -365,25 +365,24 @@
"name": "logging",
"rootUri": "../third_party/pkg/logging",
"packageUri": "lib/",
- "languageVersion": "1.5"
+ "languageVersion": "2.0"
},
{
"name": "markdown",
"rootUri": "../third_party/pkg/markdown",
"packageUri": "lib/",
- "languageVersion": "2.0"
+ "languageVersion": "2.2"
},
{
"name": "matcher",
"rootUri": "../third_party/pkg/matcher",
"packageUri": "lib/",
- "languageVersion": "2.0"
+ "languageVersion": "2.4"
},
{
"name": "meta",
"rootUri": "../pkg/meta",
- "packageUri": "lib/",
- "languageVersion": "1.12"
+ "packageUri": "lib/"
},
{
"name": "mime",
@@ -700,7 +699,7 @@
"name": "yaml",
"rootUri": "../third_party/pkg/yaml",
"packageUri": "lib/",
- "languageVersion": "2.0"
+ "languageVersion": "2.4"
}
]
}
\ No newline at end of file
diff --git a/41458.dart b/41458.dart
deleted file mode 100644
index 22bd14a..0000000
--- a/41458.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-class A {}
-
-extension AList on Iterable<A> {
- get foo => null;
-}
-
-extension AMap on Map<String, A> {
- get bar => values.foo; // <-- foo is underlined red
-}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4415ec9..90551fb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,6 +15,7 @@
* Class `OSError` now implements `Exception`. This change means `OSError` will
now be caught in catch clauses catching `Exception`s.
+* Added `InternetAddress.tryParse`.
### Tools
@@ -44,7 +45,7 @@
### Dart VM
-## 2.8.0 - 2020-04-29
+## 2.8.1 - 2020-05-06
Much of the changes in this release are in preparation for non-nullable types,
which will arrive in a future version. In anticipation of that, we have made a
diff --git a/DEPS b/DEPS
index c9b6ebe..008541f 100644
--- a/DEPS
+++ b/DEPS
@@ -36,10 +36,14 @@
"chromium_git": "https://chromium.googlesource.com",
"fuchsia_git": "https://fuchsia.googlesource.com",
+ # Checked-in SDK version. The checked-in SDK is a Dart SDK distribution in a
+ # cipd package used to run Dart scripts in the build and test infrastructure.
+ "sdk_tag": "version:2.9.0-4.0.dev",
+
# co19 is a cipd package. Use update.sh in tests/co19[_2] to update these
# hashes. It requires access to the dart-build-access group, which EngProd
# has.
- "co19_rev": "919e0b662aa4b392dcb791446d80f31e972f8635",
+ "co19_rev": "306b15d60048bee617b7d5ede9b49ebafb7d1c42",
"co19_2_rev": "368bfa9e877a2df003547f64bb17e30596af10c7",
# As Flutter does, we use Fuchsia's GN and Clang toolchain. These revision
@@ -140,7 +144,7 @@
"test_process_tag": "1.0.3",
"term_glyph_tag": "b3da31e9684a99cfe5f192b89914492018b44da7",
"test_reflective_loader_tag": "0.1.9",
- "test_tag": "test_core-v0.3.2",
+ "test_tag": "988e38ff3051f24607ad0aaf4e780835785f2ab5",
"tflite_native_rev": "3c777c40608a2a9f1427bfe0028ab48e7116b4c1",
"typed_data_tag": "1.1.6",
"usage_tag": "3.4.0",
@@ -176,7 +180,7 @@
Var("dart_root") + "/tools/sdks": {
"packages": [{
"package": "dart/dart-sdk/${{platform}}",
- "version": "version:2.8.0-dev.18.0",
+ "version": Var("sdk_tag"),
}],
"dep_type": "cipd",
},
diff --git a/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart b/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
index b274629..890d581 100644
--- a/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
@@ -1161,10 +1161,13 @@
/// variable is not in scope anymore. This should not have any effect on
/// analysis results for error-free code, because it is an error to refer to a
/// variable that is no longer in scope.
- final Map<Variable, VariableModel<Type> /*!*/ > variableInfo;
+ final Map<Variable, VariableModel<Variable, Type> /*!*/ > variableInfo;
/// Variable model for variables that have never been seen before.
- final VariableModel<Type> _freshVariableInfo;
+ final VariableModel<Variable, Type> _freshVariableInfo;
+
+ /// The empty map, used to [join] variables.
+ final Map<Variable, VariableModel<Variable, Type>> _emptyVariableMap = {};
/// Creates a state object with the given [reachable] status. All variables
/// are assumed to be unpromoted and already assigned, so joining another
@@ -1178,7 +1181,7 @@
FlowModel._(this.reachable, this.variableInfo)
: _freshVariableInfo = new VariableModel.fresh() {
assert(() {
- for (VariableModel<Type> value in variableInfo.values) {
+ for (VariableModel<Variable, Type> value in variableInfo.values) {
assert(value != null);
}
return true;
@@ -1191,7 +1194,7 @@
/// A local variable is [initialized] if its declaration has an initializer.
/// A function parameter is always initialized, so [initialized] is `true`.
FlowModel<Variable, Type> declare(Variable variable, bool initialized) {
- VariableModel<Type> newInfoForVar = _freshVariableInfo;
+ VariableModel<Variable, Type> newInfoForVar = _freshVariableInfo;
if (initialized) {
newInfoForVar = newInfoForVar.initialize();
}
@@ -1200,7 +1203,7 @@
}
/// Gets the info for the given [variable], creating it if it doesn't exist.
- VariableModel<Type> infoFor(Variable variable) =>
+ VariableModel<Variable, Type> infoFor(Variable variable) =>
variableInfo[variable] ?? _freshVariableInfo;
/// Updates the state to indicate that variables that are not definitely
@@ -1210,22 +1213,23 @@
FlowModel<Variable, Type> other,
Iterable<Variable> written,
}) {
- Map<Variable, VariableModel<Type>> newVariableInfo;
+ Map<Variable, VariableModel<Variable, Type>> newVariableInfo;
void markNotUnassigned(Variable variable) {
- VariableModel<Type> info = variableInfo[variable];
+ VariableModel<Variable, Type> info = variableInfo[variable];
if (info == null) return;
- VariableModel<Type> newInfo = info.markNotUnassigned();
+ VariableModel<Variable, Type> newInfo = info.markNotUnassigned();
if (identical(newInfo, info)) return;
- (newVariableInfo ??= new Map<Variable, VariableModel<Type>>.from(
- variableInfo))[variable] = newInfo;
+ (newVariableInfo ??=
+ new Map<Variable, VariableModel<Variable, Type>>.from(
+ variableInfo))[variable] = newInfo;
}
if (other != null) {
for (Variable variable in other.variableInfo.keys) {
- VariableModel<Type> otherInfo = other.variableInfo[variable];
+ VariableModel<Variable, Type> otherInfo = other.variableInfo[variable];
if (!otherInfo.unassigned) {
markNotUnassigned(variable);
}
@@ -1265,23 +1269,26 @@
FlowModel<Variable, Type> removePromotedAll(
Iterable<Variable> writtenVariables,
Iterable<Variable> capturedVariables) {
- Map<Variable, VariableModel<Type>> newVariableInfo;
+ Map<Variable, VariableModel<Variable, Type>> newVariableInfo;
for (Variable variable in writtenVariables) {
- VariableModel<Type> info = infoFor(variable);
+ VariableModel<Variable, Type> info = infoFor(variable);
if (info.promotedTypes != null) {
- (newVariableInfo ??= new Map<Variable, VariableModel<Type>>.from(
- variableInfo))[variable] = info.discardPromotions();
+ (newVariableInfo ??=
+ new Map<Variable, VariableModel<Variable, Type>>.from(
+ variableInfo))[variable] = info.discardPromotions();
}
}
for (Variable variable in capturedVariables) {
- VariableModel<Type> info = variableInfo[variable];
+ VariableModel<Variable, Type> info = variableInfo[variable];
if (info == null) {
- (newVariableInfo ??= new Map<Variable, VariableModel<Type>>.from(
- variableInfo))[variable] =
- new VariableModel<Type>(null, const [], false, false, true);
+ (newVariableInfo ??=
+ new Map<Variable, VariableModel<Variable, Type>>.from(
+ variableInfo))[variable] = new VariableModel<Variable, Type>(
+ null, const [], false, false, true);
} else if (!info.writeCaptured) {
- (newVariableInfo ??= new Map<Variable, VariableModel<Type>>.from(
- variableInfo))[variable] = info.writeCapture();
+ (newVariableInfo ??=
+ new Map<Variable, VariableModel<Variable, Type>>.from(
+ variableInfo))[variable] = info.writeCapture();
}
}
if (newVariableInfo == null) return this;
@@ -1314,20 +1321,20 @@
Set<Variable> unsafe) {
bool newReachable = reachable && other.reachable;
- Map<Variable, VariableModel<Type>> newVariableInfo =
- <Variable, VariableModel<Type>>{};
+ Map<Variable, VariableModel<Variable, Type>> newVariableInfo =
+ <Variable, VariableModel<Variable, Type>>{};
bool variableInfoMatchesThis = true;
bool variableInfoMatchesOther = true;
- for (MapEntry<Variable, VariableModel<Type>> entry
+ for (MapEntry<Variable, VariableModel<Variable, Type>> entry
in variableInfo.entries) {
Variable variable = entry.key;
- VariableModel<Type> thisModel = entry.value;
- VariableModel<Type> otherModel = other.variableInfo[variable];
+ VariableModel<Variable, Type> thisModel = entry.value;
+ VariableModel<Variable, Type> otherModel = other.variableInfo[variable];
if (otherModel == null) {
variableInfoMatchesThis = false;
continue;
}
- VariableModel<Type> restricted = thisModel.restrict(
+ VariableModel<Variable, Type> restricted = thisModel.restrict(
typeOperations, otherModel, unsafe.contains(variable));
newVariableInfo[variable] = restricted;
if (!identical(restricted, thisModel)) variableInfoMatchesThis = false;
@@ -1372,7 +1379,7 @@
/// potentially nullable.
ExpressionInfo<Variable, Type> tryMarkNonNullable(
TypeOperations<Variable, Type> typeOperations, Variable variable) {
- VariableModel<Type> info = infoFor(variable);
+ VariableModel<Variable, Type> info = infoFor(variable);
if (info.writeCaptured) {
return new ExpressionInfo<Variable, Type>(this, this, this);
}
@@ -1407,7 +1414,7 @@
TypeOperations<Variable, Type> typeOperations,
Variable variable,
Type type) {
- VariableModel<Type> info = infoFor(variable);
+ VariableModel<Variable, Type> info = infoFor(variable);
if (info.writeCaptured) {
return this;
}
@@ -1438,7 +1445,7 @@
TypeOperations<Variable, Type> typeOperations,
Variable variable,
Type type) {
- VariableModel<Type> info = infoFor(variable);
+ VariableModel<Variable, Type> info = infoFor(variable);
if (info.writeCaptured) {
return new ExpressionInfo<Variable, Type>(this, this, this);
}
@@ -1472,12 +1479,11 @@
/// previous type promotion is removed.
FlowModel<Variable, Type> write(Variable variable, Type writtenType,
TypeOperations<Variable, Type> typeOperations) {
- VariableModel<Type> infoForVar = variableInfo[variable];
+ VariableModel<Variable, Type> infoForVar = variableInfo[variable];
if (infoForVar == null) return this;
- Type declaredType = typeOperations.variableType(variable);
- VariableModel<Type> newInfoForVar =
- infoForVar.write(declaredType, writtenType, typeOperations);
+ VariableModel<Variable, Type> newInfoForVar =
+ infoForVar.write(variable, writtenType, typeOperations);
if (identical(newInfoForVar, infoForVar)) return this;
return _updateVariableInfo(variable, newInfoForVar);
@@ -1497,7 +1503,7 @@
FlowModel<Variable, Type> _finishTypeTest(
TypeOperations<Variable, Type> typeOperations,
Variable variable,
- VariableModel<Type> info,
+ VariableModel<Variable, Type> info,
Type testedType,
Type promotedType,
) {
@@ -1518,16 +1524,16 @@
? this
: _updateVariableInfo(
variable,
- new VariableModel<Type>(newPromotedTypes, newTested, info.assigned,
- info.unassigned, info.writeCaptured));
+ new VariableModel<Variable, Type>(newPromotedTypes, newTested,
+ info.assigned, info.unassigned, info.writeCaptured));
}
/// Returns a new [FlowModel] where the information for [variable] is replaced
/// with [model].
FlowModel<Variable, Type> _updateVariableInfo(
- Variable variable, VariableModel<Type> model) {
- Map<Variable, VariableModel<Type>> newVariableInfo =
- new Map<Variable, VariableModel<Type>>.from(variableInfo);
+ Variable variable, VariableModel<Variable, Type> model) {
+ Map<Variable, VariableModel<Variable, Type>> newVariableInfo =
+ new Map<Variable, VariableModel<Variable, Type>>.from(variableInfo);
newVariableInfo[variable] = model;
return new FlowModel<Variable, Type>._(reachable, newVariableInfo);
}
@@ -1545,6 +1551,7 @@
TypeOperations<Variable, Type> typeOperations,
FlowModel<Variable, Type> first,
FlowModel<Variable, Type> second,
+ Map<Variable, VariableModel<Variable, Type>> emptyVariableMap,
) {
if (first == null) return second;
if (second == null) return first;
@@ -1553,9 +1560,9 @@
if (!first.reachable && second.reachable) return second;
bool newReachable = first.reachable || second.reachable;
- Map<Variable, VariableModel<Type>> newVariableInfo =
- FlowModel.joinVariableInfo(
- typeOperations, first.variableInfo, second.variableInfo);
+ Map<Variable, VariableModel<Variable, Type>> newVariableInfo =
+ FlowModel.joinVariableInfo(typeOperations, first.variableInfo,
+ second.variableInfo, emptyVariableMap);
return FlowModel._identicalOrNew(
first, second, newReachable, newVariableInfo);
@@ -1563,26 +1570,32 @@
/// Joins two "variable info" maps. See [join] for details.
@visibleForTesting
- static Map<Variable, VariableModel<Type>> joinVariableInfo<Variable, Type>(
+ static Map<Variable, VariableModel<Variable, Type>>
+ joinVariableInfo<Variable, Type>(
TypeOperations<Variable, Type> typeOperations,
- Map<Variable, VariableModel<Type>> first,
- Map<Variable, VariableModel<Type>> second,
+ Map<Variable, VariableModel<Variable, Type>> first,
+ Map<Variable, VariableModel<Variable, Type>> second,
+ Map<Variable, VariableModel<Variable, Type>> emptyMap,
) {
if (identical(first, second)) return first;
- if (first.isEmpty || second.isEmpty) return const {};
+ if (first.isEmpty || second.isEmpty) {
+ return emptyMap;
+ }
- Map<Variable, VariableModel<Type>> result =
- <Variable, VariableModel<Type>>{};
+ Map<Variable, VariableModel<Variable, Type>> result =
+ <Variable, VariableModel<Variable, Type>>{};
bool alwaysFirst = true;
bool alwaysSecond = true;
- for (MapEntry<Variable, VariableModel<Type>> entry in first.entries) {
+ for (MapEntry<Variable, VariableModel<Variable, Type>> entry
+ in first.entries) {
Variable variable = entry.key;
- VariableModel<Type> secondModel = second[variable];
+ VariableModel<Variable, Type> secondModel = second[variable];
if (secondModel == null) {
alwaysFirst = false;
} else {
- VariableModel<Type> joined =
- VariableModel.join<Type>(typeOperations, entry.value, secondModel);
+ VariableModel<Variable, Type> joined =
+ VariableModel.join<Variable, Type>(
+ typeOperations, entry.value, secondModel);
result[variable] = joined;
if (!identical(joined, entry.value)) alwaysFirst = false;
if (!identical(joined, secondModel)) alwaysSecond = false;
@@ -1591,7 +1604,7 @@
if (alwaysFirst) return first;
if (alwaysSecond && result.length == second.length) return second;
- if (result.isEmpty) return const {};
+ if (result.isEmpty) return emptyMap;
return result;
}
@@ -1601,7 +1614,7 @@
FlowModel<Variable, Type> first,
FlowModel<Variable, Type> second,
bool newReachable,
- Map<Variable, VariableModel<Type>> newVariableInfo) {
+ Map<Variable, VariableModel<Variable, Type>> newVariableInfo) {
if (first.reachable == newReachable &&
identical(first.variableInfo, newVariableInfo)) {
return first;
@@ -1619,13 +1632,14 @@
/// The equivalence check is shallow; if two variables' models are not
/// identical, we return `false`.
static bool _variableInfosEqual<Variable, Type>(
- Map<Variable, VariableModel<Type>> p1,
- Map<Variable, VariableModel<Type>> p2) {
+ Map<Variable, VariableModel<Variable, Type>> p1,
+ Map<Variable, VariableModel<Variable, Type>> p2) {
if (p1.length != p2.length) return false;
if (!p1.keys.toSet().containsAll(p2.keys)) return false;
- for (MapEntry<Variable, VariableModel<Type>> entry in p1.entries) {
- VariableModel<Type> p1Value = entry.value;
- VariableModel<Type> p2Value = p2[entry.key];
+ for (MapEntry<Variable, VariableModel<Variable, Type>> entry
+ in p1.entries) {
+ VariableModel<Variable, Type> p1Value = entry.value;
+ VariableModel<Variable, Type> p2Value = p2[entry.key];
if (!identical(p1Value, p2Value)) {
return false;
}
@@ -1640,6 +1654,11 @@
/// consideration by an instance check.
Type factor(Type from, Type what);
+ /// Return `true` if the [variable] is a local variable (not a formal
+ /// parameter), and it has no declared type (no explicit type, and not
+ /// initializer).
+ bool isLocalVariableWithoutDeclaredType(Variable variable);
+
/// Returns `true` if [type1] and [type2] are the same type.
bool isSameType(Type type1, Type type2);
@@ -1667,7 +1686,7 @@
/// Instances of this class are immutable, so the methods below that "update"
/// the state actually leave `this` unchanged and return a new state object.
@visibleForTesting
-class VariableModel<Type> {
+class VariableModel<Variable, Type> {
/// Sequence of types that the variable has been promoted to, where each
/// element of the sequence is a subtype of the previous. Null if the
/// variable hasn't been promoted.
@@ -1709,35 +1728,38 @@
/// Returns a new [VariableModel] in which any promotions present have been
/// dropped.
- VariableModel<Type> discardPromotions() {
+ VariableModel<Variable, Type> discardPromotions() {
assert(promotedTypes != null, 'No promotions to discard');
- return new VariableModel<Type>(
+ return new VariableModel<Variable, Type>(
null, tested, assigned, unassigned, writeCaptured);
}
/// Returns a new [VariableModel] reflecting the fact that the variable was
/// just initialized.
- VariableModel<Type> initialize() {
+ VariableModel<Variable, Type> initialize() {
if (promotedTypes == null && tested.isEmpty && assigned && !unassigned) {
return this;
}
- return new VariableModel<Type>(null, const [], true, false, writeCaptured);
+ return new VariableModel<Variable, Type>(
+ null, const [], true, false, writeCaptured);
}
/// Returns a new [VariableModel] reflecting the fact that the variable is
/// not definitely unassigned.
- VariableModel<Type> markNotUnassigned() {
+ VariableModel<Variable, Type> markNotUnassigned() {
if (!unassigned) return this;
- return new VariableModel<Type>(
+ return new VariableModel<Variable, Type>(
promotedTypes, tested, assigned, false, writeCaptured);
}
/// Returns an updated model reflect a control path that is known to have
/// previously passed through some [other] state. See [FlowModel.restrict]
/// for details.
- VariableModel<Type> restrict(TypeOperations<Object, Type> typeOperations,
- VariableModel<Type> otherModel, bool unsafe) {
+ VariableModel<Variable, Type> restrict(
+ TypeOperations<Variable, Type> typeOperations,
+ VariableModel<Variable, Type> otherModel,
+ bool unsafe) {
List<Type> thisPromotedTypes = promotedTypes;
List<Type> otherPromotedTypes = otherModel.promotedTypes;
bool newAssigned = assigned || otherModel.assigned;
@@ -1818,8 +1840,18 @@
/// Returns a new [VariableModel] reflecting the fact that the variable was
/// just written to.
- VariableModel<Type> write(Type declaredType, Type writtenType,
- TypeOperations<Object, Type> typeOperations) {
+ VariableModel<Variable, Type> write(Variable variable, Type writtenType,
+ TypeOperations<Variable, Type> typeOperations) {
+ if (writeCaptured) {
+ return new VariableModel<Variable, Type>(
+ promotedTypes, tested, true, false, writeCaptured);
+ }
+
+ if (_isPromotableViaInitialization(typeOperations, variable)) {
+ return new VariableModel<Variable, Type>(
+ [writtenType], tested, true, false, writeCaptured);
+ }
+
List<Type> newPromotedTypes;
if (promotedTypes == null) {
newPromotedTypes = null;
@@ -1840,23 +1872,48 @@
}
}
}
+
+ Type declaredType = typeOperations.variableType(variable);
newPromotedTypes = _tryPromoteToTypeOfInterest(
typeOperations, declaredType, newPromotedTypes, writtenType);
if (identical(promotedTypes, newPromotedTypes) && assigned) return this;
+
List<Type> newTested;
if (newPromotedTypes == null && promotedTypes != null) {
newTested = const [];
} else {
newTested = tested;
}
- return new VariableModel<Type>(
+
+ return new VariableModel<Variable, Type>(
newPromotedTypes, newTested, true, false, writeCaptured);
}
/// Returns a new [VariableModel] reflecting the fact that the variable has
/// been write-captured.
- VariableModel<Type> writeCapture() {
- return new VariableModel<Type>(null, const [], assigned, false, true);
+ VariableModel<Variable, Type> writeCapture() {
+ return new VariableModel<Variable, Type>(
+ null, const [], assigned, false, true);
+ }
+
+ /// We say that a variable `x` is promotable via initialization given
+ /// variable model `VM` if `x` is a local variable (not a formal parameter)
+ /// and:
+ /// * VM = VariableModel(declared, promoted, tested,
+ /// assigned, unassigned, captured)
+ /// * and `captured` is false
+ /// * and `promoted` is empty
+ /// * and `x` is declared with no explicit type and no initializer
+ /// * and `assigned` is false and `unassigned` is true
+ bool _isPromotableViaInitialization<Variable>(
+ TypeOperations<Variable, Type> typeOperations,
+ Variable variable,
+ ) {
+ return !writeCaptured &&
+ !assigned &&
+ unassigned &&
+ promotedTypes == null &&
+ typeOperations.isLocalVariableWithoutDeclaredType(variable);
}
/// Determines whether a variable with the given [promotedTypes] should be
@@ -1867,14 +1924,11 @@
/// Note that since promotions chains are considered immutable, if promotion
/// is required, a new promotion chain will be created and returned.
List<Type> _tryPromoteToTypeOfInterest(
- TypeOperations<Object, Type> typeOperations,
+ TypeOperations<Variable, Type> typeOperations,
Type declaredType,
List<Type> promotedTypes,
Type writtenType) {
- if (writeCaptured) {
- assert(promotedTypes == null);
- return promotedTypes;
- }
+ assert(!writeCaptured);
// Figure out if we have any promotion candidates (types that are a
// supertype of writtenType and a proper subtype of the currently-promoted
@@ -1973,10 +2027,10 @@
}
/// Joins two variable models. See [FlowModel.join] for details.
- static VariableModel<Type> join<Type>(
- TypeOperations<Object, Type> typeOperations,
- VariableModel<Type> first,
- VariableModel<Type> second) {
+ static VariableModel<Variable, Type> join<Variable, Type>(
+ TypeOperations<Variable, Type> typeOperations,
+ VariableModel<Variable, Type> first,
+ VariableModel<Variable, Type> second) {
List<Type> newPromotedTypes = joinPromotedTypes(
first.promotedTypes, second.promotedTypes, typeOperations);
bool newAssigned = first.assigned && second.assigned;
@@ -1993,8 +2047,8 @@
/// chains. Briefly, we intersect given chains. The chains are totally
/// ordered subsets of a global partial order. Their intersection is a
/// subset of each, and as such is also totally ordered.
- static List<Type> joinPromotedTypes<Type>(List<Type> chain1,
- List<Type> chain2, TypeOperations<Object, Type> typeOperations) {
+ static List<Type> joinPromotedTypes<Variable, Type>(List<Type> chain1,
+ List<Type> chain2, TypeOperations<Variable, Type> typeOperations) {
if (chain1 == null) return chain1;
if (chain2 == null) return chain2;
@@ -2037,8 +2091,8 @@
/// - The sense of equality for the union operation is determined by
/// [TypeOperations.isSameType].
/// - The types of interests lists are considered immutable.
- static List<Type> joinTested<Type>(List<Type> types1, List<Type> types2,
- TypeOperations<Object, Type> typeOperations) {
+ static List<Type> joinTested<Variable, Type>(List<Type> types1,
+ List<Type> types2, TypeOperations<Variable, Type> typeOperations) {
// Ensure that types1 is the shorter list.
if (types1.length > types2.length) {
List<Type> tmp = types1;
@@ -2073,17 +2127,17 @@
? [promoted]
: (promotedTypes.toList()..add(promoted));
- static List<Type> _addTypeToUniqueList<Type>(List<Type> types, Type newType,
- TypeOperations<Object, Type> typeOperations) {
+ static List<Type> _addTypeToUniqueList<Variable, Type>(List<Type> types,
+ Type newType, TypeOperations<Variable, Type> typeOperations) {
if (_typeListContains(typeOperations, types, newType)) return types;
return new List<Type>.from(types)..add(newType);
}
/// Creates a new [VariableModel] object, unless it is equivalent to either
/// [first] or [second], in which case one of those objects is re-used.
- static VariableModel<Type> _identicalOrNew<Type>(
- VariableModel<Type> first,
- VariableModel<Type> second,
+ static VariableModel<Variable, Type> _identicalOrNew<Variable, Type>(
+ VariableModel<Variable, Type> first,
+ VariableModel<Variable, Type> second,
List<Type> newPromotedTypes,
List<Type> newTested,
bool newAssigned,
@@ -2102,13 +2156,13 @@
second.writeCaptured == newWriteCaptured) {
return second;
} else {
- return new VariableModel<Type>(newPromotedTypes, newTested, newAssigned,
- newUnassigned, newWriteCaptured);
+ return new VariableModel<Variable, Type>(newPromotedTypes, newTested,
+ newAssigned, newUnassigned, newWriteCaptured);
}
}
- static bool _typeListContains<Type>(
- TypeOperations<Object, Type> typeOperations,
+ static bool _typeListContains<Variable, Type>(
+ TypeOperations<Variable, Type> typeOperations,
List<Type> list,
Type searchType) {
for (Type type in list) {
@@ -2825,7 +2879,7 @@
FlowModel<Variable, Type> _join(
FlowModel<Variable, Type> first, FlowModel<Variable, Type> second) =>
- FlowModel.join(typeOperations, first, second);
+ FlowModel.join(typeOperations, first, second, _current._emptyVariableMap);
/// Associates [expression], which should be the most recently visited
/// expression, with the given [expressionInfo] object, and updates the
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/forwarding_listener.dart b/pkg/_fe_analyzer_shared/lib/src/parser/forwarding_listener.dart
index dfd9be9..a241b0f 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/forwarding_listener.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/forwarding_listener.dart
@@ -629,8 +629,8 @@
@override
void endExtensionDeclaration(
- Token extensionKeyword, Token onKeyword, Token token) {
- listener?.endExtensionDeclaration(extensionKeyword, onKeyword, token);
+ Token extensionKeyword, Token onKeyword, Token endToken) {
+ listener?.endExtensionDeclaration(extensionKeyword, onKeyword, endToken);
}
@override
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart b/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart
index 0877766..d284d8a 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart
@@ -225,7 +225,7 @@
/// - on type
/// - body
void endExtensionDeclaration(
- Token extensionKeyword, Token onKeyword, Token token) {
+ Token extensionKeyword, Token onKeyword, Token endToken) {
logEvent('ExtensionDeclaration');
}
diff --git a/pkg/_fe_analyzer_shared/pubspec.yaml b/pkg/_fe_analyzer_shared/pubspec.yaml
index cb6e229..8870c1c 100644
--- a/pkg/_fe_analyzer_shared/pubspec.yaml
+++ b/pkg/_fe_analyzer_shared/pubspec.yaml
@@ -1,5 +1,5 @@
name: _fe_analyzer_shared
-version: 2.2.0
+version: 3.0.0
description: Logic that is shared between the front_end and analyzer packages.
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/_fe_analyzer_shared
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart
index 16800f0..67bd777 100644
--- a/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart
@@ -2266,6 +2266,21 @@
});
});
});
+
+ test('promote via initialization', () {
+ var h = _Harness();
+ var x = _Var('x', null, isLocalVariableWithoutDeclaredType: true);
+
+ var s1 = FlowModel<_Var, _Type>(true).declare(x, false);
+ expect(s1.variableInfo, {
+ x: _matchVariableModel(chain: null),
+ });
+
+ var s2 = s1.write(x, _Type('int'), h);
+ expect(s2.variableInfo, {
+ x: _matchVariableModel(chain: ['int']),
+ });
+ });
});
group('declare', () {
@@ -2829,12 +2844,17 @@
var intType = _Type('int');
var intQType = _Type('int?');
var stringType = _Type('String');
- const emptyMap = <Null, VariableModel<Null>>{};
+ const emptyMap = const <_Var, VariableModel<_Var, _Type>>{};
- VariableModel<_Type> model(List<_Type> promotionChain,
- [List<_Type> typesOfInterest]) =>
- VariableModel<_Type>(promotionChain,
- typesOfInterest ?? promotionChain ?? [], false, true, false);
+ VariableModel<_Var, _Type> model(List<_Type> promotionChain,
+ {List<_Type> typesOfInterest, bool assigned = false}) =>
+ VariableModel<_Var, _Type>(
+ promotionChain,
+ typesOfInterest ?? promotionChain ?? [],
+ assigned,
+ !assigned,
+ false,
+ );
group('without input reuse', () {
test('promoted with unpromoted', () {
@@ -2847,7 +2867,7 @@
x: model(null),
y: model([intType])
};
- expect(FlowModel.joinVariableInfo(h, p1, p2), {
+ expect(FlowModel.joinVariableInfo(h, p1, p2, emptyMap), {
x: _matchVariableModel(chain: null, ofInterest: ['int']),
y: _matchVariableModel(chain: null, ofInterest: ['int'])
});
@@ -2860,7 +2880,7 @@
x: model([intType]),
y: model([stringType])
};
- expect(FlowModel.joinVariableInfo(h, p, p), same(p));
+ expect(FlowModel.joinVariableInfo(h, p, p, emptyMap), same(p));
});
test('one input empty', () {
@@ -2869,9 +2889,9 @@
x: model([intType]),
y: model([stringType])
};
- var p2 = <_Var, VariableModel<_Type>>{};
- expect(FlowModel.joinVariableInfo(h, p1, p2), same(emptyMap));
- expect(FlowModel.joinVariableInfo(h, p2, p1), same(emptyMap));
+ var p2 = <_Var, VariableModel<_Var, _Type>>{};
+ expect(FlowModel.joinVariableInfo(h, p1, p2, emptyMap), same(emptyMap));
+ expect(FlowModel.joinVariableInfo(h, p2, p1, emptyMap), same(emptyMap));
});
test('promoted with unpromoted', () {
@@ -2883,8 +2903,8 @@
var expected = {
x: _matchVariableModel(chain: null, ofInterest: ['int'])
};
- expect(FlowModel.joinVariableInfo(h, p1, p2), expected);
- expect(FlowModel.joinVariableInfo(h, p2, p1), expected);
+ expect(FlowModel.joinVariableInfo(h, p1, p2, emptyMap), expected);
+ expect(FlowModel.joinVariableInfo(h, p2, p1, emptyMap), expected);
});
test('related type chains', () {
@@ -2898,8 +2918,8 @@
var expected = {
x: _matchVariableModel(chain: ['int?'], ofInterest: ['int?', 'int'])
};
- expect(FlowModel.joinVariableInfo(h, p1, p2), expected);
- expect(FlowModel.joinVariableInfo(h, p2, p1), expected);
+ expect(FlowModel.joinVariableInfo(h, p1, p2, emptyMap), expected);
+ expect(FlowModel.joinVariableInfo(h, p2, p1, emptyMap), expected);
});
test('unrelated type chains', () {
@@ -2913,8 +2933,8 @@
var expected = {
x: _matchVariableModel(chain: null, ofInterest: ['String', 'int'])
};
- expect(FlowModel.joinVariableInfo(h, p1, p2), expected);
- expect(FlowModel.joinVariableInfo(h, p2, p1), expected);
+ expect(FlowModel.joinVariableInfo(h, p1, p2, emptyMap), expected);
+ expect(FlowModel.joinVariableInfo(h, p2, p1, emptyMap), expected);
});
test('sub-map', () {
@@ -2925,8 +2945,8 @@
y: model([stringType])
};
var p2 = {x: xModel};
- expect(FlowModel.joinVariableInfo(h, p1, p2), same(p2));
- expect(FlowModel.joinVariableInfo(h, p2, p1), same(p2));
+ expect(FlowModel.joinVariableInfo(h, p1, p2, emptyMap), same(p2));
+ expect(FlowModel.joinVariableInfo(h, p2, p1, emptyMap), same(p2));
});
test('sub-map with matched subtype', () {
@@ -2941,8 +2961,8 @@
var expected = {
x: _matchVariableModel(chain: ['int?'], ofInterest: ['int?', 'int'])
};
- expect(FlowModel.joinVariableInfo(h, p1, p2), expected);
- expect(FlowModel.joinVariableInfo(h, p2, p1), expected);
+ expect(FlowModel.joinVariableInfo(h, p1, p2, emptyMap), expected);
+ expect(FlowModel.joinVariableInfo(h, p2, p1, emptyMap), expected);
});
test('sub-map with mismatched subtype', () {
@@ -2957,24 +2977,24 @@
var expected = {
x: _matchVariableModel(chain: ['int?'], ofInterest: ['int?', 'int'])
};
- expect(FlowModel.joinVariableInfo(h, p1, p2), expected);
- expect(FlowModel.joinVariableInfo(h, p2, p1), expected);
+ expect(FlowModel.joinVariableInfo(h, p1, p2, emptyMap), expected);
+ expect(FlowModel.joinVariableInfo(h, p2, p1, emptyMap), expected);
});
test('assigned', () {
var h = _Harness();
- var intQModel = model([intQType]);
- var writtenModel = intQModel.write(intQType, _Type('Object?'), h);
- var p1 = {x: writtenModel, y: writtenModel, z: intQModel, w: intQModel};
- var p2 = {x: writtenModel, y: intQModel, z: writtenModel, w: intQModel};
- var joined = FlowModel.joinVariableInfo(h, p1, p2);
+ var unassigned = model(null, assigned: false);
+ var assigned = model(null, assigned: true);
+ var p1 = {x: assigned, y: assigned, z: unassigned, w: unassigned};
+ var p2 = {x: assigned, y: unassigned, z: assigned, w: unassigned};
+ var joined = FlowModel.joinVariableInfo(h, p1, p2, emptyMap);
expect(joined, {
- x: same(writtenModel),
+ x: same(assigned),
y: _matchVariableModel(
chain: null, assigned: false, unassigned: false),
z: _matchVariableModel(
chain: null, assigned: false, unassigned: false),
- w: same(intQModel)
+ w: same(unassigned)
});
});
@@ -2994,7 +3014,7 @@
z: writeCapturedModel,
w: intQModel
};
- var joined = FlowModel.joinVariableInfo(h, p1, p2);
+ var joined = FlowModel.joinVariableInfo(h, p1, p2, emptyMap);
expect(joined, {
x: same(writeCapturedModel),
y: same(writeCapturedModel),
@@ -3053,7 +3073,7 @@
Matcher assignedMatcher = wrapMatcher(assigned);
Matcher unassignedMatcher = wrapMatcher(unassigned);
Matcher writeCapturedMatcher = wrapMatcher(writeCaptured);
- return predicate((VariableModel<_Type> model) {
+ return predicate((VariableModel<_Var, _Type> model) {
if (!chainMatcher.matches(model.promotedTypes, {})) return false;
if (!ofInterestMatcher.matches(model.tested, {})) return false;
if (!assignedMatcher.matches(model.assigned, {})) return false;
@@ -3322,6 +3342,11 @@
if_(isNotType(variableRead(variable), type), ifTrue);
}
+ @override
+ bool isLocalVariableWithoutDeclaredType(_Var variable) {
+ return variable.isLocalVariableWithoutDeclaredType;
+ }
+
/// Creates a [LazyExpression] representing an `is!` check, checking whether
/// [subExpression] has the given [type].
LazyExpression isNotType(LazyExpression subExpression, String type) {
@@ -3475,10 +3500,14 @@
class _Var {
final String name;
-
final _Type type;
+ final bool isLocalVariableWithoutDeclaredType;
- _Var(this.name, this.type);
+ _Var(
+ this.name,
+ this.type, {
+ this.isLocalVariableWithoutDeclaredType = false,
+ });
@override
String toString() => '$type $name';
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/declaration.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/declaration.dart
new file mode 100644
index 0000000..099a022
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/declaration.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// The tests in this file exercise various kinds of constructs that initialize a
+// variable at its declaration site. We verify that the variable is not
+// considered "written to" for purposes of defeating type promotions inside
+// closures.
+
+parameter(Object a) {
+ if (a is int) {
+ () {
+ /*int*/ a;
+ };
+ }
+}
+
+localParameter() {
+ localFunction(Object a) {
+ if (a is int) {
+ () {
+ /*int*/ a;
+ };
+ }
+ }
+
+ (Object b) {
+ if (b is int) {
+ () {
+ /*int*/ b;
+ };
+ }
+ };
+}
+
+localVariable() {
+ Object a = 1;
+ if (a is int) {
+ () {
+ /*int*/ a;
+ };
+ }
+}
+
+class MyStackTrace implements StackTrace {
+ noSuchMethod(invocation) => super.noSuchMethod(invocation);
+}
+
+catchParameters() {
+ try {} on Object catch (e, st) {
+ if (e is int) {
+ () {
+ /*int*/ e;
+ };
+ }
+ if (st is MyStackTrace) {
+ () {
+ /*MyStackTrace*/ st;
+ };
+ }
+ }
+}
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/initialization.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/initialization.dart
index 099a022..6425744 100644
--- a/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/initialization.dart
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/initialization.dart
@@ -1,62 +1,95 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// The tests in this file exercise various kinds of constructs that initialize a
-// variable at its declaration site. We verify that the variable is not
-// considered "written to" for purposes of defeating type promotions inside
-// closures.
-
-parameter(Object a) {
- if (a is int) {
- () {
- /*int*/ a;
- };
- }
-}
-
-localParameter() {
- localFunction(Object a) {
- if (a is int) {
- () {
- /*int*/ a;
- };
- }
- }
-
- (Object b) {
- if (b is int) {
- () {
- /*int*/ b;
- };
- }
- };
-}
+// The tests in this file exercise "promotable via initialization" part of
+// the flow analysis specification.
localVariable() {
- Object a = 1;
- if (a is int) {
- () {
- /*int*/ a;
- };
- }
+ var x;
+ x = 1;
+ /*int*/ x;
+ x = 2.3;
+ x;
}
-class MyStackTrace implements StackTrace {
- noSuchMethod(invocation) => super.noSuchMethod(invocation);
+localVariable_hasInitializer(num a) {
+ var x = a;
+ x = 1;
+ x;
}
-catchParameters() {
- try {} on Object catch (e, st) {
- if (e is int) {
- () {
- /*int*/ e;
- };
- }
- if (st is MyStackTrace) {
- () {
- /*MyStackTrace*/ st;
- };
- }
+localVariable_hasTypeAnnotation() {
+ num x;
+ x = 1;
+ x;
+}
+
+localVariable_hasTypeAnnotation_dynamic() {
+ dynamic x;
+ x = 1;
+ x;
+}
+
+localVariable_ifElse_differentTypes(bool a) {
+ var x;
+ if (a) {
+ x = 0;
+ /*int*/ x;
+ } else {
+ x = 1.2;
+ /*double*/ x;
}
+ x;
+}
+
+localVariable_ifElse_sameTypes(bool a) {
+ var x;
+ if (a) {
+ x = 0;
+ /*int*/ x;
+ } else {
+ x = 1;
+ /*int*/ x;
+ }
+ /*int*/ x;
+}
+
+localVariable_notDefinitelyUnassigned(bool a) {
+ var x;
+ if (a) {
+ x = 1.2;
+ }
+ x = 1;
+ x;
+}
+
+localVariable_notDefinitelyUnassigned_hasLocalFunction() {
+ var x;
+
+ void f() {
+ // Note, no assignment to 'x', but because 'x' is assigned somewhere in
+ // the enclosing function, it is not definitely unassigned in 'f'.
+ // So, when we join after 'f' declaration, we make 'x' not definitely
+ // unassigned in the enclosing function as well.
+ }
+
+ f();
+
+ x = 1;
+ x;
+}
+
+parameter(x) {
+ x = 1;
+ x;
+}
+
+parameterLocal() {
+ void f(x) {
+ x = 1;
+ x;
+ }
+
+ f(0);
}
diff --git a/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart b/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart
index 61ffb29..916bcf7 100644
--- a/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart
+++ b/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart
@@ -102,8 +102,7 @@
if (element is engine.ClassElement) {
if (element.isEnum) {
return ElementKind.ENUM;
- }
- if (element.isMixin) {
+ } else if (element.isMixin) {
return ElementKind.MIXIN;
}
}
diff --git a/pkg/analysis_server/lib/src/cider/fixes.dart b/pkg/analysis_server/lib/src/cider/fixes.dart
new file mode 100644
index 0000000..5a19221
--- /dev/null
+++ b/pkg/analysis_server/lib/src/cider/fixes.dart
@@ -0,0 +1,66 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+import 'package:analysis_server/plugin/edit/fix/fix_core.dart';
+import 'package:analysis_server/src/services/correction/change_workspace.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/correction/fix_internal.dart';
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/src/dart/analysis/performance_logger.dart';
+import 'package:analyzer/src/dart/micro/resolve_file.dart';
+import 'package:meta/meta.dart';
+
+class CiderErrorFixes {
+ final AnalysisError error;
+
+ /// The fixes for the [error], might be empty.
+ final List<Fix> fixes;
+
+ CiderErrorFixes({
+ @required this.error,
+ @required this.fixes,
+ });
+}
+
+class CiderFixesComputer {
+ final PerformanceLog _logger;
+ final FileResolver _fileResolver;
+
+ CiderFixesComputer(this._logger, this._fileResolver);
+
+ /// Compute quick fixes for errors on the line with the [offset].
+ Future<List<CiderErrorFixes>> compute(String path, int offset) async {
+ var result = <CiderErrorFixes>[];
+ var resolvedUnit = _fileResolver.resolve(path);
+
+ var lineInfo = resolvedUnit.lineInfo;
+ var requestLine = lineInfo.getLocation(offset).lineNumber;
+
+ await _logger.runAsync('Compute fixes', () async {
+ for (var error in resolvedUnit.errors) {
+ var errorLine = lineInfo.getLocation(error.offset).lineNumber;
+ if (errorLine == requestLine) {
+ var workspace = DartChangeWorkspace([resolvedUnit.session]);
+ var context = DartFixContextImpl(
+ workspace,
+ resolvedUnit,
+ error,
+ (name) => const [],
+ );
+
+ var fixes = await DartFixContributor().computeFixes(context);
+ fixes.sort(Fix.SORT_BY_RELEVANCE);
+
+ result.add(
+ CiderErrorFixes(error: error, fixes: fixes),
+ );
+ }
+ }
+ });
+
+ return result;
+ }
+}
diff --git a/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart b/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart
index 1b62c51..79e549c 100644
--- a/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart
+++ b/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart
@@ -71,18 +71,24 @@
}
}
+protocol.CompletionAvailableSuggestionsParams
+ createCompletionAvailableSuggestions(
+ List<Library> changed,
+ List<int> removed,
+) =>
+ protocol.CompletionAvailableSuggestionsParams(
+ changedLibraries: changed.map((library) {
+ return _protocolAvailableSuggestionSet(library);
+ }).toList(),
+ removedLibraries: removed,
+ );
+
/// Convert the [LibraryChange] into the corresponding protocol notification.
protocol.Notification createCompletionAvailableSuggestionsNotification(
List<Library> changed,
List<int> removed,
-) {
- return protocol.CompletionAvailableSuggestionsParams(
- changedLibraries: changed.map((library) {
- return _protocolAvailableSuggestionSet(library);
- }).toList(),
- removedLibraries: removed,
- ).toNotification();
-}
+) =>
+ createCompletionAvailableSuggestions(changed, removed).toNotification();
/// Compute existing imports and elements that they provide.
protocol.Notification createExistingImportsNotification(
diff --git a/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart b/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart
index 1f83281..48ecb59 100644
--- a/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart
+++ b/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart
@@ -12,6 +12,7 @@
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:charcode/charcode.dart';
+import 'package:meta/meta.dart';
import 'package:nnbd_migration/api_for_analysis_server/dartfix_listener_interface.dart';
import 'package:nnbd_migration/api_for_analysis_server/http_preview_server.dart';
import 'package:nnbd_migration/api_for_analysis_server/instrumentation_listener.dart';
@@ -31,10 +32,12 @@
// TODO(srawlins): Refactor to use
// `Feature.non_nullable.firstSupportedVersion` when this becomes non-null.
- static const String _intendedMinimumSdkVersion = '2.8.0';
+ static const String _intendedMinimumSdkVersion = '2.9.0';
static const String _intendedSdkVersionConstraint =
- '>=$_intendedMinimumSdkVersion <3.0.0';
+ '>=$_intendedMinimumSdkVersion <2.10.0';
+
+ static final List<HttpPreviewServer> _allServers = [];
final int preferredPort;
@@ -104,6 +107,7 @@
if (enablePreview && _server == null) {
_server = HttpPreviewServer(state, rerun, preferredPort);
_server.serveHttp();
+ _allServers.add(_server);
port = await _server.boundPort;
authToken = await _server.authToken;
}
@@ -193,7 +197,7 @@
insertAfterParent(environmentOptions.span, content);
} else if (sdk is YamlScalar) {
var currentConstraint = VersionConstraint.parse(sdk.value);
- var minimumVersion = Version.parse('2.8.0');
+ var minimumVersion = Version.parse(_intendedMinimumSdkVersion);
if (currentConstraint is VersionRange &&
currentConstraint.min >= minimumVersion) {
// The current SDK version constraint already enables Null Safety.
@@ -263,6 +267,18 @@
_server?.close();
}
+ /// Allows unit tests to shut down any rogue servers that have been started,
+ /// so that unit testing can complete.
+ @visibleForTesting
+ static void shutdownAllServers() {
+ for (var server in _allServers) {
+ try {
+ server.close();
+ } catch (_) {}
+ }
+ _allServers.clear();
+ }
+
static void task(DartFixRegistrar registrar, DartFixListener listener,
EditDartfixParams params) {
registrar.registerCodeTask(NonNullableFix(listener,
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/extension_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/extension_member_contributor.dart
index 1eb2d01..7f16627 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/extension_member_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/extension_member_contributor.dart
@@ -64,7 +64,7 @@
}
}
- return memberBuilder.suggestions.toList();
+ return const <CompletionSuggestion>[];
}
if (expression.isSynthetic) {
@@ -97,7 +97,7 @@
_addExtensionMembers(containingLibrary, type);
expression.staticType;
}
- return memberBuilder.suggestions.toList();
+ return const <CompletionSuggestion>[];
}
void _addExtensionMembers(LibraryElement containingLibrary, DartType type) {
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/feature_computer.dart b/pkg/analysis_server/lib/src/services/completion/dart/feature_computer.dart
index 7fd4bc0..c6ed836 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/feature_computer.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/feature_computer.dart
@@ -119,7 +119,7 @@
/// Return the value of the _has deprecated_ feature for the given [element].
double hasDeprecatedFeature(Element element) {
- return element.hasDeprecated ? 0.0 : 1.0;
+ return element.hasOrInheritsDeprecated ? 0.0 : 1.0;
}
/// Return the inheritance distance between the [subclass] and the
@@ -539,3 +539,19 @@
return null;
}
}
+
+/// Additional behavior for elements related to the computation of features.
+extension ElementExtension on Element {
+ /// Return `true` if this element, or any enclosing element, has been
+ /// annotated with the `@deprecated` annotation.
+ bool get hasOrInheritsDeprecated {
+ var element = this;
+ while (element != null) {
+ if (element.hasDeprecated) {
+ return true;
+ }
+ element = element.enclosingElement;
+ }
+ return false;
+ }
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/field_formal_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/field_formal_contributor.dart
index f82ddfb..2b7bae3 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/field_formal_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/field_formal_contributor.dart
@@ -19,6 +19,9 @@
Future<List<CompletionSuggestion>> computeSuggestions(
DartCompletionRequest request, SuggestionBuilder builder) async {
var node = request.target.containingNode;
+ // TODO(brianwilkerson) We should suggest field formal parameters even if
+ // the user hasn't already typed the `this.` prefix, by including the
+ // prefix in the completion.
if (node is! FieldFormalParameter) {
return const <CompletionSuggestion>[];
}
@@ -29,10 +32,11 @@
}
// Compute the list of fields already referenced in the constructor.
+ // TODO(brianwilkerson) This doesn't include fields in initializers, which
+ // shouldn't be suggested.
var referencedFields = <String>[];
for (var param in constructor.parameters.parameters) {
- if (param is DefaultFormalParameter &&
- param.parameter is FieldFormalParameter) {
+ if (param is DefaultFormalParameter) {
param = (param as DefaultFormalParameter).parameter;
}
if (param is FieldFormalParameter) {
@@ -52,30 +56,21 @@
}
// Add suggestions for fields that are not already referenced.
- var relevance = request.useNewRelevance
- ? Relevance.fieldFormalParameter
- : DART_RELEVANCE_LOCAL_FIELD;
- var suggestions = <CompletionSuggestion>[];
for (var member in enclosingClass.members) {
if (member is FieldDeclaration && !member.isStatic) {
for (var variable in member.fields.variables) {
- var fieldId = variable.name;
- if (fieldId != null) {
- var fieldName = fieldId.name;
+ var field = variable.name.staticElement;
+ if (field != null) {
+ var fieldName = field.name;
if (fieldName != null && fieldName.isNotEmpty) {
if (!referencedFields.contains(fieldName)) {
- var suggestion = createSuggestion(
- request, fieldId.staticElement,
- relevance: relevance);
- if (suggestion != null) {
- suggestions.add(suggestion);
- }
+ builder.suggestFieldFormalParameter(field);
}
}
}
}
}
}
- return suggestions;
+ return const <CompletionSuggestion>[];
}
}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/inherited_reference_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/inherited_reference_contributor.dart
index bcc6898..f1f1db2 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/inherited_reference_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/inherited_reference_contributor.dart
@@ -39,7 +39,7 @@
if (classOrMixin is ClassOrMixinDeclaration &&
classOrMixin.declaredElement != null) {
memberBuilder = MemberSuggestionBuilder(request, builder);
- return _computeSuggestionsForClass(classOrMixin.declaredElement, request);
+ _computeSuggestionsForClass(classOrMixin.declaredElement, request);
}
return const <CompletionSuggestion>[];
}
@@ -87,7 +87,7 @@
}
}
- List<CompletionSuggestion> _computeSuggestionsForClass(
+ void _computeSuggestionsForClass(
ClassElement classElement, DartCompletionRequest request) {
var isFunctionalArgument = request.target.isFunctionalArgument();
kind = isFunctionalArgument
@@ -102,7 +102,6 @@
_addSuggestionsForType(type, request, inheritanceDistance,
isFunctionalArgument: isFunctionalArgument);
}
- return memberBuilder.suggestions.toList();
}
/// Return the class member containing the target or `null` if the target is
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart
index 5681497..19e0d3a 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart
@@ -6,21 +6,19 @@
import 'package:analysis_server/src/computer/computer_hover.dart';
import 'package:analysis_server/src/protocol_server.dart'
- show CompletionSuggestion, CompletionSuggestionKind, Location;
+ show CompletionSuggestion, CompletionSuggestionKind;
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/feature_computer.dart';
import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
import 'package:analysis_server/src/services/completion/dart/utilities.dart';
import 'package:analysis_server/src/utilities/strings.dart';
-import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/dart/element/type_provider.dart';
import 'package:analyzer/src/util/comment.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart' as protocol
- show Element, ElementKind;
+ show ElementKind;
import 'package:analyzer_plugin/src/utilities/completion/optype.dart';
import 'package:analyzer_plugin/src/utilities/visitors/local_declaration_visitor.dart'
show LocalDeclarationVisitor;
@@ -59,9 +57,14 @@
node = node.parent.parent;
}
- var visitor =
- _LocalVisitor(request, suggestLocalFields: suggestLocalFields);
- visitor.visit(node);
+ var visitor = _LocalVisitor(request, builder,
+ suggestLocalFields: suggestLocalFields);
+ try {
+ builder.laterReplacesEarlier = false;
+ visitor.visit(node);
+ } finally {
+ builder.laterReplacesEarlier = true;
+ }
return visitor.suggestions;
}
}
@@ -75,6 +78,9 @@
/// The request for which suggestions are being computed.
final DartCompletionRequest request;
+ /// The builder used to build the suggestions.
+ final SuggestionBuilder builder;
+
/// The op type associated with the request.
final OpType opType;
@@ -99,7 +105,7 @@
/// Only used when [useNewRelevance] is `false`.
int privateMemberRelevance = DART_RELEVANCE_DEFAULT;
- _LocalVisitor(this.request, {@required this.suggestLocalFields})
+ _LocalVisitor(this.request, this.builder, {@required this.suggestLocalFields})
: opType = request.opType,
useNewRelevance = request.useNewRelevance,
targetIsFunctionalArgument = request.target.isFunctionalArgument(),
@@ -139,54 +145,31 @@
TypeProvider get typeProvider => request.libraryElement.typeProvider;
+ CompletionSuggestionKind get _defaultKind => targetIsFunctionalArgument
+ ? CompletionSuggestionKind.IDENTIFIER
+ : opType.suggestKind;
+
@override
void declaredClass(ClassDeclaration declaration) {
if (opType.includeTypeNameSuggestions) {
- _addLocalSuggestion_includeTypeNameSuggestions(
- declaration.declaredElement,
- declaration.name,
- NO_RETURN_TYPE,
- protocol.ElementKind.CLASS,
- isAbstract: declaration.isAbstract,
- isDeprecated: isDeprecated(declaration),
- type: _instantiateClassElement(declaration.declaredElement),
- );
+ builder.suggestClass(declaration.declaredElement, kind: _defaultKind);
}
}
@override
void declaredClassTypeAlias(ClassTypeAlias declaration) {
if (opType.includeTypeNameSuggestions) {
- _addLocalSuggestion_includeTypeNameSuggestions(
- declaration.declaredElement,
- declaration.name,
- NO_RETURN_TYPE,
- protocol.ElementKind.CLASS_TYPE_ALIAS,
- isAbstract: true,
- isDeprecated: isDeprecated(declaration),
- type: _instantiateClassElement(declaration.declaredElement),
- );
+ builder.suggestClass(declaration.declaredElement, kind: _defaultKind);
}
}
@override
void declaredEnum(EnumDeclaration declaration) {
if (opType.includeTypeNameSuggestions) {
- _addLocalSuggestion_includeTypeNameSuggestions(
- declaration.declaredElement,
- declaration.name,
- NO_RETURN_TYPE,
- protocol.ElementKind.ENUM,
- isDeprecated: isDeprecated(declaration),
- type: _instantiateClassElement(declaration.declaredElement),
- );
+ builder.suggestClass(declaration.declaredElement, kind: _defaultKind);
for (var enumConstant in declaration.constants) {
if (!enumConstant.isSynthetic) {
- _addLocalSuggestion_includeReturnValueSuggestions_enumConstant(
- enumConstant,
- declaration,
- isDeprecated: isDeprecated(declaration),
- );
+ builder.suggestEnumConstant(enumConstant.declaredElement);
}
}
}
@@ -195,14 +178,7 @@
@override
void declaredExtension(ExtensionDeclaration declaration) {
if (opType.includeReturnValueSuggestions && declaration.name != null) {
- _addLocalSuggestion_includeReturnValueSuggestions(
- declaration.declaredElement,
- declaration.name,
- NO_RETURN_TYPE,
- protocol.ElementKind.EXTENSION,
- isDeprecated: isDeprecated(declaration),
- type: null,
- );
+ builder.suggestExtension(declaration.declaredElement, kind: _defaultKind);
}
}
@@ -277,32 +253,16 @@
@override
void declaredFunctionTypeAlias(FunctionTypeAlias declaration) {
if (opType.includeTypeNameSuggestions) {
- // TODO (danrubel) determine parameters and return type
- _addLocalSuggestion_includeTypeNameSuggestions(
- declaration.declaredElement,
- declaration.name,
- declaration.returnType,
- protocol.ElementKind.FUNCTION_TYPE_ALIAS,
- isAbstract: true,
- isDeprecated: isDeprecated(declaration),
- type: _instantiateFunctionTypeAlias(declaration.declaredElement),
- );
+ builder.suggestFunctionTypeAlias(declaration.declaredElement,
+ kind: _defaultKind);
}
}
@override
void declaredGenericTypeAlias(GenericTypeAlias declaration) {
if (opType.includeTypeNameSuggestions) {
- // TODO (danrubel) determine parameters and return type
- _addLocalSuggestion_includeTypeNameSuggestions(
- declaration.declaredElement,
- declaration.name,
- declaration.functionType?.returnType,
- protocol.ElementKind.FUNCTION_TYPE_ALIAS,
- isAbstract: true,
- isDeprecated: isDeprecated(declaration),
- type: _instantiateFunctionTypeAlias(declaration.declaredElement),
- );
+ builder.suggestFunctionTypeAlias(declaration.declaredElement,
+ kind: _defaultKind);
}
}
@@ -339,6 +299,11 @@
if ((opType.includeReturnValueSuggestions ||
opType.includeVoidReturnSuggestions) &&
(!opType.inStaticMethodBody || declaration.isStatic)) {
+// var method = declaration.declaredElement;
+// // TODO(brianwilkerson) Use request.featureComputer.inheritanceDistance to
+// // compute the inheritance distance.
+// var inheritanceDistance = -1.0;
+// builder.suggestMethod(method, inheritanceDistance: inheritanceDistance, kind: _defaultKind);
protocol.ElementKind elemKind;
FormalParameterList param;
var typeName = declaration.returnType;
@@ -383,15 +348,7 @@
@override
void declaredMixin(MixinDeclaration declaration) {
if (opType.includeTypeNameSuggestions) {
- _addLocalSuggestion_includeTypeNameSuggestions(
- declaration.declaredElement,
- declaration.name,
- NO_RETURN_TYPE,
- protocol.ElementKind.MIXIN,
- isAbstract: true,
- isDeprecated: isDeprecated(declaration),
- type: _instantiateClassElement(declaration.declaredElement),
- );
+ builder.suggestClass(declaration.declaredElement, kind: _defaultKind);
}
}
@@ -421,6 +378,7 @@
VariableDeclarationList varList, VariableDeclaration varDecl) {
if (opType.includeReturnValueSuggestions) {
var variableElement = varDecl.declaredElement;
+// builder.suggestTopLevelPropertyAccessor((variableElement as TopLevelVariableElement).getter);
var variableType = variableElement.type;
int relevance;
if (useNewRelevance) {
@@ -472,9 +430,7 @@
if (id == null) {
return null;
}
- kind ??= targetIsFunctionalArgument
- ? CompletionSuggestionKind.IDENTIFIER
- : opType.suggestKind;
+ kind ??= _defaultKind;
var suggestion = _createLocalSuggestion(
id, isDeprecated, relevance, typeName,
classDecl: classDecl, kind: kind);
@@ -499,32 +455,6 @@
}
}
- void _addLocalSuggestion_enumConstant(
- EnumConstantDeclaration constantDeclaration,
- EnumDeclaration enumDeclaration,
- {bool isDeprecated = false,
- int relevance = DART_RELEVANCE_DEFAULT}) {
- var constantNameNode = constantDeclaration.name;
- var constantName = constantNameNode.name;
- var enumName = enumDeclaration.name.name;
- var completion = '$enumName.$constantName';
- if (!useNewRelevance) {
- relevance = isDeprecated ? DART_RELEVANCE_LOW : relevance;
- }
- var suggestion = CompletionSuggestion(CompletionSuggestionKind.INVOCATION,
- relevance, completion, completion.length, 0, isDeprecated, false,
- returnType: enumName);
-
- suggestionMap.putIfAbsent(suggestion.completion, () => suggestion);
- var flags = protocol.Element.makeFlags(
- isDeprecated: isDeprecated,
- isPrivate: Identifier.isPrivateName(constantName));
- suggestion.element = protocol.Element(
- protocol.ElementKind.ENUM_CONSTANT, constantName, flags,
- location: Location(request.source.fullName, constantNameNode.offset,
- constantNameNode.length, 0, 0));
- }
-
void _addLocalSuggestion_includeReturnValueSuggestions(
Element element,
SimpleIdentifier id,
@@ -549,47 +479,6 @@
}
}
- void _addLocalSuggestion_includeReturnValueSuggestions_enumConstant(
- EnumConstantDeclaration constantDeclaration,
- EnumDeclaration enumDeclaration,
- {@required bool isDeprecated}) {
- var enumElement = enumDeclaration.declaredElement;
- int relevance;
- if (useNewRelevance) {
- relevance = _relevanceForType(enumElement.thisType);
- } else {
- relevance = opType.returnValueSuggestionsFilter(
- _instantiateClassElement(enumElement), DART_RELEVANCE_DEFAULT);
- }
- if (relevance != null) {
- _addLocalSuggestion_enumConstant(constantDeclaration, enumDeclaration,
- isDeprecated: isDeprecated, relevance: relevance);
- }
- }
-
- void _addLocalSuggestion_includeTypeNameSuggestions(
- Element element,
- SimpleIdentifier id,
- TypeAnnotation typeName,
- protocol.ElementKind elemKind,
- {bool isAbstract = false,
- bool isDeprecated = false,
- @required DartType type}) {
- int relevance;
- if (useNewRelevance) {
- relevance = _relevanceForType(type);
- } else {
- relevance =
- opType.typeNameSuggestionsFilter(type, DART_RELEVANCE_DEFAULT);
- }
- if (relevance != null) {
- _addLocalSuggestion(element, id, typeName, elemKind,
- isAbstract: isAbstract,
- isDeprecated: isDeprecated,
- relevance: relevance);
- }
- }
-
void _addParameterInfo(
CompletionSuggestion suggestion, FormalParameterList parameters) {
var paramList = parameters.parameters;
@@ -661,44 +550,6 @@
return suggestion;
}
- InterfaceType _instantiateClassElement(ClassElement element) {
- var typeParameters = element.typeParameters;
- var typeArguments = const <DartType>[];
- if (typeParameters.isNotEmpty) {
- typeArguments = typeParameters.map((t) {
- return typeProvider.dynamicType;
- }).toList();
- }
-
- var nullabilitySuffix = request.featureSet.isEnabled(Feature.non_nullable)
- ? NullabilitySuffix.none
- : NullabilitySuffix.star;
-
- return element.instantiate(
- typeArguments: typeArguments,
- nullabilitySuffix: nullabilitySuffix,
- );
- }
-
- FunctionType _instantiateFunctionTypeAlias(FunctionTypeAliasElement element) {
- var typeParameters = element.typeParameters;
- var typeArguments = const <DartType>[];
- if (typeParameters.isNotEmpty) {
- typeArguments = typeParameters.map((t) {
- return typeProvider.dynamicType;
- }).toList();
- }
-
- var nullabilitySuffix = request.featureSet.isEnabled(Feature.non_nullable)
- ? NullabilitySuffix.none
- : NullabilitySuffix.star;
-
- return element.instantiate(
- typeArguments: typeArguments,
- nullabilitySuffix: nullabilitySuffix,
- );
- }
-
bool _isVoid(TypeAnnotation returnType) {
if (returnType is TypeName) {
var id = returnType.name;
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart
index b6760de..28c0d6f 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart
@@ -10,13 +10,11 @@
hide CompletionSuggestion, CompletionSuggestionKind;
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
-import 'package:analysis_server/src/utilities/extensions/ast.dart';
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/source/source_range.dart';
import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
@@ -28,24 +26,14 @@
@override
Future<List<CompletionSuggestion>> computeSuggestions(
DartCompletionRequest request, SuggestionBuilder builder) async {
- var target = request.target;
- var containingNode = target.containingNode;
- var classDecl =
- containingNode.thisOrAncestorOfType<ClassOrMixinDeclaration>();
+ var targetId = _getTargetId(request.target);
+ if (targetId == null) {
+ return const <CompletionSuggestion>[];
+ }
+ var classDecl = targetId.thisOrAncestorOfType<ClassOrMixinDeclaration>();
if (classDecl == null) {
return const <CompletionSuggestion>[];
}
- if (containingNode.inClassMemberBody) {
- return const <CompletionSuggestion>[];
- }
-
- var comment = containingNode.thisOrAncestorOfType<Comment>();
- if (target.isCommentText || comment != null) {
- return const <CompletionSuggestion>[];
- }
-
- var sourceRange = _getTargetSourceRange(target);
- sourceRange ??= range.startOffsetEndOffset(request.offset, 0);
var inheritance = InheritanceManager3();
@@ -65,7 +53,7 @@
if (element.returnType != null) {
var invokeSuper = interface.isSuperImplemented(name);
var suggestion =
- await _buildSuggestion(request, sourceRange, element, invokeSuper);
+ await _buildSuggestion(request, targetId, element, invokeSuper);
if (suggestion != null) {
suggestions.add(suggestion);
}
@@ -74,17 +62,17 @@
return suggestions;
}
- /// Build a suggestion to replace [sourceRange] in the given [request] with an
+ /// Build a suggestion to replace [targetId] in the given [request] with an
/// override of the given [element].
Future<CompletionSuggestion> _buildSuggestion(
DartCompletionRequest request,
- SourceRange sourceRange,
+ SimpleIdentifier targetId,
ExecutableElement element,
bool invokeSuper) async {
var displayTextBuffer = StringBuffer();
var builder = DartChangeBuilder(request.result.session);
await builder.addFileEdit(request.result.path, (builder) {
- builder.addReplacement(sourceRange, (builder) {
+ builder.addReplacement(range.node(targetId), (builder) {
builder.writeOverride(
element,
displayTextBuffer: displayTextBuffer,
@@ -114,7 +102,7 @@
if (selectionRange == null) {
return null;
}
- var offsetDelta = sourceRange.offset + replacement.indexOf(completion);
+ var offsetDelta = targetId.offset + replacement.indexOf(completion);
var displayText =
displayTextBuffer.isNotEmpty ? displayTextBuffer.toString() : null;
var suggestion = CompletionSuggestion(
@@ -130,6 +118,24 @@
return suggestion;
}
+ /// If the target looks like a partial identifier inside a class declaration
+ /// then return that identifier, otherwise return `null`.
+ SimpleIdentifier _getTargetId(CompletionTarget target) {
+ var node = target.containingNode;
+ if (node is ClassOrMixinDeclaration) {
+ var entity = target.entity;
+ if (entity is FieldDeclaration) {
+ return _getTargetIdFromVarList(entity.fields);
+ }
+ } else if (node is FieldDeclaration) {
+ var entity = target.entity;
+ if (entity is VariableDeclarationList) {
+ return _getTargetIdFromVarList(entity);
+ }
+ }
+ return null;
+ }
+
SimpleIdentifier _getTargetIdFromVarList(VariableDeclarationList fields) {
var variables = fields.variables;
if (variables.length == 1) {
@@ -151,29 +157,6 @@
return null;
}
- /// If the target looks like a partial identifier inside a class declaration
- /// then return that identifier [SourceRange], otherwise return `null`.
- SourceRange _getTargetSourceRange(CompletionTarget target) {
- var containingNode = target.containingNode;
- if (containingNode is ClassOrMixinDeclaration) {
- if (target.entity is FieldDeclaration) {
- var fieldDecl = target.entity as FieldDeclaration;
- var simpleIdentifier = _getTargetIdFromVarList(fieldDecl.fields);
- if (simpleIdentifier != null) {
- return range.node(simpleIdentifier);
- }
- }
- } else if (containingNode is FieldDeclaration) {
- if (target.entity is VariableDeclarationList) {
- var simpleIdentifier = _getTargetIdFromVarList(target.entity);
- if (simpleIdentifier != null) {
- return range.node(simpleIdentifier);
- }
- }
- }
- return null;
- }
-
/// Return `true` if the given [node] has an `override` annotation.
bool _hasOverride(AstNode node) {
if (node is AnnotatedNode) {
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
index e7e5e69..6a4aeed 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
@@ -41,7 +41,7 @@
}
kind ??= CompletionSuggestionKind.INVOCATION;
var suggestion = CompletionSuggestion(kind, relevance, completion,
- completion.length, 0, element.hasDeprecated, false);
+ completion.length, 0, element.hasOrInheritsDeprecated, false);
// Attach docs.
var doc = DartUnitHoverComputer.computeDocumentation(
@@ -204,93 +204,21 @@
/// compared.
final Map<String, int> _completionTypesGenerated = HashMap<String, int>();
- /// A map from a completion identifier to a completion suggestion.
- final Map<String, CompletionSuggestion> _suggestionMap =
- <String, CompletionSuggestion>{};
-
MemberSuggestionBuilder(this.request, this.builder);
- Iterable<CompletionSuggestion> get suggestions => _suggestionMap.values;
-
- /// Add the given completion [suggestion].
- void addCompletionSuggestion(CompletionSuggestion suggestion) {
- _suggestionMap[suggestion.completion] = suggestion;
- }
-
- /// Add a suggestion for the given [method].
- CompletionSuggestion addSuggestionForAccessor(
+ /// Add a suggestion for the given [accessor].
+ void addSuggestionForAccessor(
{@required PropertyAccessorElement accessor,
String containingMethodName,
@required double inheritanceDistance}) {
- int oldRelevance() {
- if (accessor.hasDeprecated) {
- return DART_RELEVANCE_LOW;
+ if (accessor.isAccessibleIn(request.libraryElement)) {
+ var member = accessor.isSynthetic ? accessor.variable : accessor;
+ if (_shouldAddSuggestion(member)) {
+ builder.suggestAccessor(accessor,
+ containingMemberName: containingMethodName,
+ inheritanceDistance: inheritanceDistance);
}
- var identifier = accessor.displayName;
- if (identifier != null && identifier.startsWith(r'$')) {
- // Decrease relevance of suggestions starting with $
- // https://github.com/dart-lang/sdk/issues/27303
- return DART_RELEVANCE_LOW;
- }
- return DART_RELEVANCE_DEFAULT;
}
-
- if (!accessor.isAccessibleIn(request.libraryElement)) {
- // Don't suggest private members from imported libraries.
- return null;
- }
- if (accessor.isSynthetic) {
- // Avoid visiting a field twice. All fields induce a getter, but only
- // non-final fields induce a setter, so we don't add a suggestion for a
- // synthetic setter.
- if (accessor.isGetter) {
- var variable = accessor.variable;
- int relevance;
- if (request.useNewRelevance) {
- var featureComputer = request.featureComputer;
- var contextType = featureComputer.contextTypeFeature(
- request.contextType, variable.type);
- var hasDeprecated = featureComputer.hasDeprecatedFeature(accessor);
- var startsWithDollar =
- featureComputer.startsWithDollarFeature(accessor.name);
- var superMatches = featureComputer.superMatchesFeature(
- containingMethodName, accessor.name);
- relevance = _computeRelevance(
- contextType: contextType,
- hasDeprecated: hasDeprecated,
- inheritanceDistance: inheritanceDistance,
- startsWithDollar: startsWithDollar,
- superMatches: superMatches);
- } else {
- relevance = oldRelevance();
- }
- return _addSuggestion(variable, relevance);
- }
- } else {
- var type =
- accessor.isGetter ? accessor.returnType : accessor.parameters[0].type;
- int relevance;
- if (request.useNewRelevance) {
- var featureComputer = request.featureComputer;
- var contextType =
- featureComputer.contextTypeFeature(request.contextType, type);
- var hasDeprecated = featureComputer.hasDeprecatedFeature(accessor);
- var startsWithDollar =
- featureComputer.startsWithDollarFeature(accessor.name);
- var superMatches = featureComputer.superMatchesFeature(
- containingMethodName, accessor.name);
- relevance = _computeRelevance(
- contextType: contextType,
- hasDeprecated: hasDeprecated,
- inheritanceDistance: inheritanceDistance,
- startsWithDollar: startsWithDollar,
- superMatches: superMatches);
- } else {
- relevance = oldRelevance();
- }
- return _addSuggestion(accessor, relevance);
- }
- return null;
}
/// Add a suggestion for the given [method].
@@ -302,61 +230,15 @@
if (method.isAccessibleIn(request.libraryElement) &&
_shouldAddSuggestion(method)) {
builder.suggestMethod(method,
- containingMethodName: containingMethodName,
+ containingMemberName: containingMethodName,
kind: kind,
inheritanceDistance: inheritanceDistance);
}
}
- /// Add a suggestion for the given [element] with the given [relevance],
- /// provided that it is not shadowed by a previously added suggestion.
- CompletionSuggestion _addSuggestion(Element element, int relevance,
- {CompletionSuggestionKind kind}) {
- if (!_shouldAddSuggestion(element)) {
- return null;
- }
- var suggestion =
- createSuggestion(request, element, kind: kind, relevance: relevance);
- if (suggestion != null) {
- addCompletionSuggestion(suggestion);
- }
- return suggestion;
- }
-
- /// Compute a relevance value from the given feature scores:
- /// - [contextType] is higher if the type of the element matches the context
- /// type,
- /// - [hasDeprecated] is higher if the element is not deprecated,
- /// - [inheritanceDistance] is higher if the element is defined closer to the
- /// target type,
- /// - [startsWithDollar] is higher if the element's name doe _not_ start with
- /// a dollar sign, and
- /// - [superMatches] is higher if the element is being invoked through `super`
- /// and the element's name matches the name of the enclosing method.
- int _computeRelevance(
- {@required double contextType,
- @required double hasDeprecated,
- @required double inheritanceDistance,
- @required double startsWithDollar,
- @required double superMatches}) {
- var score = weightedAverage([
- contextType,
- hasDeprecated,
- inheritanceDistance,
- startsWithDollar,
- superMatches
- ], [
- 1.0,
- 0.5,
- 1.0,
- 0.5,
- 1.0
- ]);
- return toRelevance(score, Relevance.member);
- }
-
/// Return `true` if a suggestion for the given [element] should be created.
bool _shouldAddSuggestion(Element element) {
+ // TODO(brianwilkerson) Consider moving this into SuggestionBuilder.
var identifier = element.displayName;
var alreadyGenerated = _completionTypesGenerated.putIfAbsent(
@@ -405,8 +287,16 @@
/// The completion request for which suggestions are being built.
final DartCompletionRequest request;
- /// A collection of completion suggestions.
- final List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
+ /// A map from a completion identifier to a completion suggestion.
+ final Map<String, CompletionSuggestion> _suggestionMap =
+ <String, CompletionSuggestion>{};
+
+ /// A flag indicating whether a suggestion should replace any earlier
+ /// suggestions for the same completion (`true`) or whether earlier
+ /// suggestions should take priority over more recent suggestions.
+ // TODO(brianwilkerson) Attempt to convert the contributors so that a single
+ // approach is followed.
+ bool laterReplacesEarlier = true;
/// A flag indicating whether the [_cachedContextType] has been computed.
bool _hasContextType = false;
@@ -429,6 +319,10 @@
/// flavor of Flutter being used.
Flutter get flutter => _flutter ??= Flutter.of(request.result);
+ /// Return an iterable that can be used to access the completion suggestions
+ /// that have been built.
+ Iterable<CompletionSuggestion> get suggestions => _suggestionMap.values;
+
DartType get _contextType {
if (!_hasContextType) {
_hasContextType = true;
@@ -438,21 +332,90 @@
return _cachedContextType;
}
- /// Add a suggestion for the [classElement].
+ /// Add a suggestion for the [accessor]. If the accessor is being invoked with
+ /// a target of `super`, then the [containingMemberName] should be the name of
+ /// the member containing the invocation. The [inheritanceDistance] is the
+ /// value of the inheritance distance feature computed for the method.
+ void suggestAccessor(PropertyAccessorElement accessor,
+ {String containingMemberName, @required double inheritanceDistance}) {
+ if (accessor.isSynthetic) {
+ // Avoid visiting a field twice. All fields induce a getter, but only
+ // non-final fields induce a setter, so we don't add a suggestion for a
+ // synthetic setter.
+ if (accessor.isGetter) {
+ var variable = accessor.variable;
+ int relevance;
+ if (request.useNewRelevance) {
+ var featureComputer = request.featureComputer;
+ var contextType = featureComputer.contextTypeFeature(
+ request.contextType, variable.type);
+ var elementKind = featureComputer.elementKindFeature(
+ variable, request.opType.completionLocation);
+ var hasDeprecated = featureComputer.hasDeprecatedFeature(accessor);
+ var startsWithDollar =
+ featureComputer.startsWithDollarFeature(accessor.name);
+ var superMatches = featureComputer.superMatchesFeature(
+ containingMemberName, accessor.name);
+ relevance = _computeMemberRelevance(
+ contextType: contextType,
+ elementKind: elementKind,
+ hasDeprecated: hasDeprecated,
+ inheritanceDistance: inheritanceDistance,
+ startsWithDollar: startsWithDollar,
+ superMatches: superMatches);
+ } else {
+ relevance = _computeOldMemberRelevance(accessor);
+ }
+ _add(createSuggestion(request, variable, relevance: relevance));
+ }
+ } else {
+ var type =
+ accessor.isGetter ? accessor.returnType : accessor.parameters[0].type;
+ int relevance;
+ if (request.useNewRelevance) {
+ var featureComputer = request.featureComputer;
+ var contextType =
+ featureComputer.contextTypeFeature(request.contextType, type);
+ var elementKind = featureComputer.elementKindFeature(
+ accessor, request.opType.completionLocation);
+ var hasDeprecated = featureComputer.hasDeprecatedFeature(accessor);
+ var startsWithDollar =
+ featureComputer.startsWithDollarFeature(accessor.name);
+ var superMatches = featureComputer.superMatchesFeature(
+ containingMemberName, accessor.name);
+ relevance = _computeMemberRelevance(
+ contextType: contextType,
+ elementKind: elementKind,
+ hasDeprecated: hasDeprecated,
+ inheritanceDistance: inheritanceDistance,
+ startsWithDollar: startsWithDollar,
+ superMatches: superMatches);
+ } else {
+ relevance = _computeOldMemberRelevance(accessor);
+ }
+ _add(createSuggestion(request, accessor, relevance: relevance));
+ }
+ }
+
+ /// Add a suggestion for the [classElement]. If a [kind] is provided it will
+ /// be used as the kind for the suggestion.
void suggestClass(ClassElement classElement,
{CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION}) {
int relevance;
if (request.useNewRelevance) {
relevance = _computeTopLevelRelevance(classElement,
elementType: _instantiateClassElement(classElement));
- } else if (classElement.hasDeprecated) {
+ } else if (classElement.hasOrInheritsDeprecated) {
relevance = DART_RELEVANCE_LOW;
} else {
relevance = request.opType.typeNameSuggestionsFilter(
_instantiateClassElement(classElement), DART_RELEVANCE_DEFAULT);
+ if (relevance == null) {
+ return;
+ }
}
- suggestions.add(createSuggestion(request, classElement,
+ _add(createSuggestion(request, classElement,
kind: kind, relevance: relevance));
}
@@ -487,16 +450,17 @@
if (request.useNewRelevance) {
relevance = _computeTopLevelRelevance(constructor);
} else {
- relevance = constructor.hasDeprecated
+ relevance = constructor.hasOrInheritsDeprecated
? DART_RELEVANCE_LOW
: DART_RELEVANCE_DEFAULT;
}
- suggestions.add(createSuggestion(request, constructor,
+ _add(createSuggestion(request, constructor,
completion: completion, kind: kind, relevance: relevance));
}
- /// Add a suggestion for the [element].
+ /// Add a suggestion for the top-level [element]. If a [kind] is provided it
+ /// will be used as the kind for the suggestion.
void suggestElement(Element element,
{CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION}) {
if (element is ClassElement) {
@@ -518,7 +482,33 @@
}
}
- /// Add a suggestion for the [extension].
+ /// Add a suggestion for the enum [constant].
+ void suggestEnumConstant(FieldElement constant) {
+ var constantName = constant.name;
+ var enumElement = constant.enclosingElement;
+ var enumName = enumElement.name;
+ var completion = '$enumName.$constantName';
+
+ int relevance;
+ if (request.useNewRelevance) {
+ relevance =
+ _computeTopLevelRelevance(constant, elementType: constant.type);
+ } else if (constant.hasOrInheritsDeprecated) {
+ relevance = DART_RELEVANCE_LOW;
+ } else {
+ relevance = request.opType.returnValueSuggestionsFilter(
+ _instantiateClassElement(enumElement), DART_RELEVANCE_DEFAULT);
+ if (relevance == null) {
+ return;
+ }
+ }
+
+ _add(createSuggestion(request, constant,
+ completion: completion, relevance: relevance));
+ }
+
+ /// Add a suggestion for the [extension]. If a [kind] is provided it will be
+ /// used as the kind for the suggestion.
void suggestExtension(ExtensionElement extension,
{CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION}) {
int relevance;
@@ -526,14 +516,26 @@
relevance = _computeTopLevelRelevance(extension,
elementType: extension.extendedType);
} else {
- relevance =
- extension.hasDeprecated ? DART_RELEVANCE_LOW : DART_RELEVANCE_DEFAULT;
+ relevance = extension.hasOrInheritsDeprecated
+ ? DART_RELEVANCE_LOW
+ : DART_RELEVANCE_DEFAULT;
}
- suggestions.add(
+ _add(
createSuggestion(request, extension, kind: kind, relevance: relevance));
}
+ /// Add a suggestion to reference the [field] in a field formal parameter.
+ void suggestFieldFormalParameter(FieldElement field) {
+ // TODO(brianwilkerson) Add a parameter (`bool includePrefix`) indicating
+ // whether to include the `this.` prefix in the completion.
+ var relevance = request.useNewRelevance
+ ? Relevance.fieldFormalParameter
+ : DART_RELEVANCE_LOCAL_FIELD;
+
+ _add(createSuggestion(request, field, relevance: relevance));
+ }
+
/// Add a suggestion for the `call` method defined on functions.
void suggestFunctionCall() {
const callString = 'call()';
@@ -543,7 +545,7 @@
typeParameters: null,
parameters: null,
returnType: 'void');
- suggestions.add(CompletionSuggestion(
+ _add(CompletionSuggestion(
CompletionSuggestionKind.INVOCATION,
request.useNewRelevance ? Relevance.callFunction : DART_RELEVANCE_HIGH,
callString,
@@ -557,21 +559,23 @@
));
}
- /// Add a suggestion for the [functionTypeAlias].
+ /// Add a suggestion for the [functionTypeAlias]. If a [kind] is provided it
+ /// will be used as the kind for the suggestion.
void suggestFunctionTypeAlias(FunctionTypeAliasElement functionTypeAlias,
{CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION}) {
int relevance;
if (request.useNewRelevance) {
- relevance =
- _computeTopLevelRelevance(functionTypeAlias, defaultRelevance: 750);
+ relevance = _computeTopLevelRelevance(functionTypeAlias,
+ defaultRelevance: 750,
+ elementType: _instantiateFunctionTypeAlias(functionTypeAlias));
+ } else if (functionTypeAlias.hasOrInheritsDeprecated) {
+ relevance = DART_RELEVANCE_LOW;
} else {
- relevance = functionTypeAlias.hasDeprecated
- ? DART_RELEVANCE_LOW
- : (functionTypeAlias.library == request.libraryElement
- ? DART_RELEVANCE_LOCAL_FUNCTION
- : DART_RELEVANCE_DEFAULT);
+ relevance = functionTypeAlias.library == request.libraryElement
+ ? DART_RELEVANCE_LOCAL_FUNCTION
+ : DART_RELEVANCE_DEFAULT;
}
- suggestions.add(createSuggestion(request, functionTypeAlias,
+ _add(createSuggestion(request, functionTypeAlias,
kind: kind, relevance: relevance));
}
@@ -584,55 +588,48 @@
// than a fixed value.
relevance = Relevance.loadLibrary;
} else {
- relevance =
- function.hasDeprecated ? DART_RELEVANCE_LOW : DART_RELEVANCE_DEFAULT;
+ relevance = function.hasOrInheritsDeprecated
+ ? DART_RELEVANCE_LOW
+ : DART_RELEVANCE_DEFAULT;
}
- suggestions.add(createSuggestion(request, function, relevance: relevance));
+ _add(createSuggestion(request, function, relevance: relevance));
}
+ /// Add a suggestion for the [method]. If the method is being invoked with a
+ /// target of `super`, then the [containingMemberName] should be the name of
+ /// the member containing the invocation. If a [kind] is provided it will be
+ /// used as the kind for the suggestion. The [inheritanceDistance] is the
+ /// value of the inheritance distance feature computed for the method.
void suggestMethod(MethodElement method,
- {String containingMethodName,
+ {String containingMemberName,
CompletionSuggestionKind kind,
@required double inheritanceDistance}) {
// TODO(brianwilkerson) Refactor callers so that we're passing in the type
// of the target (assuming we don't already have that type available via
// the [request]) and compute the [inheritanceDistance] in this method.
- int oldRelevance() {
- if (method.hasDeprecated) {
- return DART_RELEVANCE_LOW;
- } else if (method.name == containingMethodName) {
- // Boost the relevance of a super expression calling a method of the
- // same name as the containing method.
- return DART_RELEVANCE_HIGH;
- }
- var identifier = method.displayName;
- if (identifier != null && identifier.startsWith(r'$')) {
- // Decrease relevance of suggestions starting with $
- // https://github.com/dart-lang/sdk/issues/27303
- return DART_RELEVANCE_LOW;
- }
- return DART_RELEVANCE_DEFAULT;
- }
-
int relevance;
if (request.useNewRelevance) {
var featureComputer = request.featureComputer;
var contextType = featureComputer.contextTypeFeature(
request.contextType, method.returnType);
+ var elementKind = featureComputer.elementKindFeature(
+ method, request.opType.completionLocation);
var hasDeprecated = featureComputer.hasDeprecatedFeature(method);
var startsWithDollar =
featureComputer.startsWithDollarFeature(method.name);
var superMatches = featureComputer.superMatchesFeature(
- containingMethodName, method.name);
+ containingMemberName, method.name);
relevance = _computeMemberRelevance(
contextType: contextType,
+ elementKind: elementKind,
hasDeprecated: hasDeprecated,
inheritanceDistance: inheritanceDistance,
startsWithDollar: startsWithDollar,
superMatches: superMatches);
} else {
- relevance = oldRelevance();
+ relevance = _computeOldMemberRelevance(method,
+ containingMethodName: containingMemberName);
}
var suggestion =
@@ -663,30 +660,31 @@
suggestion.requiredParameterCount = null;
suggestion.hasNamedParameters = null;
}
- suggestions.add(suggestion);
+ _add(suggestion);
}
}
- /// Add a suggestion for the top-level [function].
+ /// Add a suggestion for the top-level [function]. If a [kind] is provided it
+ /// will be used as the kind for the suggestion.
void suggestTopLevelFunction(FunctionElement function,
{CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION}) {
int relevance;
if (request.useNewRelevance) {
relevance =
_computeTopLevelRelevance(function, elementType: function.returnType);
+ } else if (function.hasOrInheritsDeprecated) {
+ relevance = DART_RELEVANCE_LOW;
} else {
- relevance = function.hasDeprecated
- ? DART_RELEVANCE_LOW
- : (function.library == request.libraryElement
- ? DART_RELEVANCE_LOCAL_FUNCTION
- : DART_RELEVANCE_DEFAULT);
+ relevance = function.library == request.libraryElement
+ ? DART_RELEVANCE_LOCAL_FUNCTION
+ : DART_RELEVANCE_DEFAULT;
}
- suggestions.add(
- createSuggestion(request, function, kind: kind, relevance: relevance));
+ _add(createSuggestion(request, function, kind: kind, relevance: relevance));
}
- /// Add a suggestion for the top-level property [accessor].
+ /// Add a suggestion for the top-level property [accessor]. If a [kind] is
+ /// provided it will be used as the kind for the suggestion.
void suggestTopLevelPropertyAccessor(PropertyAccessorElement accessor,
{CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION}) {
if (accessor.isSetter && accessor.isSynthetic) {
@@ -704,16 +702,26 @@
if (request.useNewRelevance) {
relevance =
_computeTopLevelRelevance(variable, elementType: variable.type);
+ } else if (accessor.hasOrInheritsDeprecated) {
+ relevance = DART_RELEVANCE_LOW;
} else {
- relevance = accessor.hasDeprecated
- ? DART_RELEVANCE_LOW
- : (variable.library == request.libraryElement
- ? DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE
- : DART_RELEVANCE_DEFAULT);
+ relevance = variable.library == request.libraryElement
+ ? DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE
+ : DART_RELEVANCE_DEFAULT;
}
- suggestions.add(
- createSuggestion(request, variable, kind: kind, relevance: relevance));
+ _add(createSuggestion(request, variable, kind: kind, relevance: relevance));
+ }
+
+ /// Add the given [suggestion] if it isn't `null`.
+ void _add(protocol.CompletionSuggestion suggestion) {
+ if (suggestion != null) {
+ if (laterReplacesEarlier) {
+ _suggestionMap[suggestion.completion] = suggestion;
+ } else {
+ _suggestionMap.putIfAbsent(suggestion.completion, () => suggestion);
+ }
+ }
}
/// Compute a relevance value from the given feature scores:
@@ -728,18 +736,21 @@
/// and the element's name matches the name of the enclosing method.
int _computeMemberRelevance(
{@required double contextType,
+ @required double elementKind,
@required double hasDeprecated,
@required double inheritanceDistance,
@required double startsWithDollar,
@required double superMatches}) {
var score = weightedAverage([
contextType,
+ elementKind,
hasDeprecated,
inheritanceDistance,
startsWithDollar,
superMatches
], [
1.0,
+ 0.75,
0.5,
1.0,
0.5,
@@ -748,6 +759,25 @@
return toRelevance(score, Relevance.member);
}
+ /// Compute the old relevance score for a member.
+ int _computeOldMemberRelevance(Element member,
+ {String containingMethodName}) {
+ if (member.hasOrInheritsDeprecated) {
+ return DART_RELEVANCE_LOW;
+ } else if (member.name == containingMethodName) {
+ // Boost the relevance of a super expression calling a method of the
+ // same name as the containing method.
+ return DART_RELEVANCE_HIGH;
+ }
+ var identifier = member.displayName;
+ if (identifier != null && identifier.startsWith(r'$')) {
+ // Decrease relevance of suggestions starting with $
+ // https://github.com/dart-lang/sdk/issues/27303
+ return DART_RELEVANCE_LOW;
+ }
+ return DART_RELEVANCE_DEFAULT;
+ }
+
/// Return the relevance score for a top-level [element].
int _computeTopLevelRelevance(Element element,
{int defaultRelevance = 800, DartType elementType}) {
@@ -763,7 +793,7 @@
var hasDeprecated = featureComputer.hasDeprecatedFeature(element);
return toRelevance(
weightedAverage(
- [contextTypeFeature, elementKind, hasDeprecated], [0.8, 0.8, 0.2]),
+ [contextTypeFeature, elementKind, hasDeprecated], [1.0, 0.75, 0.2]),
defaultRelevance);
}
@@ -784,4 +814,22 @@
nullabilitySuffix: nullabilitySuffix,
);
}
+
+ FunctionType _instantiateFunctionTypeAlias(FunctionTypeAliasElement element) {
+ var typeParameters = element.typeParameters;
+ var typeArguments = const <DartType>[];
+ if (typeParameters.isNotEmpty) {
+ var neverType = request.libraryElement.typeProvider.neverType;
+ typeArguments = List.filled(typeParameters.length, neverType);
+ }
+
+ var nullabilitySuffix = request.featureSet.isEnabled(Feature.non_nullable)
+ ? NullabilitySuffix.none
+ : NullabilitySuffix.star;
+
+ return element.instantiate(
+ typeArguments: typeArguments,
+ nullabilitySuffix: nullabilitySuffix,
+ );
+ }
}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
index 491bfac..3fce378 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
@@ -103,7 +103,6 @@
var memberBuilder = _SuggestionBuilder(request, builder);
memberBuilder.buildSuggestions(type, containingMethodName,
mixins: mixins, superclassConstraints: superclassConstraints);
- return memberBuilder.suggestions.toList();
} else if (type is FunctionType) {
builder.suggestFunctionCall();
}
diff --git a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
index 8ab9a0f..1b83baf 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
@@ -175,7 +175,6 @@
}
var change = builder.sourceChange;
if (change.edits.isEmpty) {
- _coverageMarker();
return;
}
change.id = kind.id;
@@ -374,12 +373,10 @@
node is AssignmentExpression ||
node is Statement ||
node is ThrowExpression) {
- _coverageMarker();
return;
}
}
if (expressionStatement == null) {
- _coverageMarker();
return;
}
// prepare expression
@@ -388,7 +385,6 @@
// prepare expression type
var type = expression.staticType;
if (type.isVoid) {
- _coverageMarker();
return;
}
// prepare excluded names
@@ -641,7 +637,6 @@
body is EmptyFunctionBody ||
body.isAsynchronous ||
body.isGenerator) {
- _coverageMarker();
return;
}
@@ -673,7 +668,6 @@
var body = _getEnclosingFunctionBody();
// prepare expression body
if (body is! ExpressionFunctionBody || body.isGenerator) {
- _coverageMarker();
return;
}
@@ -682,7 +676,6 @@
// Return expressions can be quite large, e.g. Flutter build() methods.
// It is surprising to see this Quick Assist deep in the function body.
if (selectionOffset >= returnValue.offset) {
- _coverageMarker();
return;
}
@@ -809,13 +802,11 @@
(node) => node is ForStatement && node.forLoopParts is ForEachParts)
as ForStatement;
if (forEachStatement == null) {
- _coverageMarker();
return;
}
ForEachParts forEachParts = forEachStatement.forLoopParts;
if (selectionOffset < forEachStatement.offset ||
forEachStatement.rightParenthesis.end < selectionOffset) {
- _coverageMarker();
return;
}
// loop should declare variable
@@ -823,7 +814,6 @@
? forEachParts.loopVariable
: null;
if (loopVariable == null) {
- _coverageMarker();
return;
}
// iterable should be VariableElement
@@ -833,7 +823,6 @@
iterable.staticElement is VariableElement) {
listName = iterable.name;
} else {
- _coverageMarker();
return;
}
// iterable should be List
@@ -841,13 +830,11 @@
var iterableType = iterable.staticType;
if (iterableType is! InterfaceType ||
iterableType.element != typeProvider.listElement) {
- _coverageMarker();
return;
}
}
// body should be Block
if (forEachStatement.body is! Block) {
- _coverageMarker();
return;
}
Block body = forEachStatement.body;
@@ -863,7 +850,6 @@
} else if (!conflicts.contains('k')) {
indexName = 'k';
} else {
- _coverageMarker();
return;
}
}
@@ -892,30 +878,25 @@
}
// prepare "is"
if (node is! IsExpression) {
- _coverageMarker();
return;
}
var isExpression = node as IsExpression;
if (isExpression.notOperator != null) {
- _coverageMarker();
return;
}
// prepare enclosing ()
var parent = isExpression.parent;
if (parent is! ParenthesizedExpression) {
- _coverageMarker();
return;
}
var parExpression = parent as ParenthesizedExpression;
// prepare enclosing !()
var parent2 = parent.parent;
if (parent2 is! PrefixExpression) {
- _coverageMarker();
return;
}
var prefExpression = parent2 as PrefixExpression;
if (prefExpression.operator.type != TokenType.BANG) {
- _coverageMarker();
return;
}
@@ -943,31 +924,26 @@
}
// prepare !()
if (node is! PrefixExpression) {
- _coverageMarker();
return;
}
var prefExpression = node as PrefixExpression;
// should be ! operator
if (prefExpression.operator.type != TokenType.BANG) {
- _coverageMarker();
return;
}
// prepare !()
var operand = prefExpression.operand;
if (operand is! ParenthesizedExpression) {
- _coverageMarker();
return;
}
var parExpression = operand as ParenthesizedExpression;
operand = parExpression.expression;
// prepare "is"
if (operand is! IsExpression) {
- _coverageMarker();
return;
}
var isExpression = operand as IsExpression;
if (isExpression.notOperator != null) {
- _coverageMarker();
return;
}
@@ -1007,31 +983,26 @@
}
}
if (isEmptyIdentifier == null) {
- _coverageMarker();
return;
}
// should be "isEmpty"
var propertyElement = isEmptyIdentifier.staticElement;
if (propertyElement == null || 'isEmpty' != propertyElement.name) {
- _coverageMarker();
return;
}
// should have "isNotEmpty"
var propertyTarget = propertyElement.enclosingElement;
if (propertyTarget == null ||
getChildren(propertyTarget, 'isNotEmpty').isEmpty) {
- _coverageMarker();
return;
}
// should be in PrefixExpression
if (isEmptyAccess.parent is! PrefixExpression) {
- _coverageMarker();
return;
}
var prefixExpression = isEmptyAccess.parent as PrefixExpression;
// should be !
if (prefixExpression.operator.type != TokenType.BANG) {
- _coverageMarker();
return;
}
@@ -1118,29 +1089,24 @@
// find FieldDeclaration
var fieldDeclaration = node.thisOrAncestorOfType<FieldDeclaration>();
if (fieldDeclaration == null) {
- _coverageMarker();
return;
}
// not interesting for static
if (fieldDeclaration.isStatic) {
- _coverageMarker();
return;
}
// has a parse error
var variableList = fieldDeclaration.fields;
if (variableList.keyword == null && variableList.type == null) {
- _coverageMarker();
return;
}
// not interesting for final
if (variableList.isFinal) {
- _coverageMarker();
return;
}
// should have exactly one field
List<VariableDeclaration> fields = variableList.variables;
if (fields.length != 1) {
- _coverageMarker();
return;
}
var field = fields.first;
@@ -1149,12 +1115,10 @@
// should have a public name
var name = nameNode.name;
if (Identifier.isPrivateName(name)) {
- _coverageMarker();
return;
}
// should be on the name
if (nameNode != node) {
- _coverageMarker();
return;
}
var changeBuilder = _newDartChangeBuilder();
@@ -1227,7 +1191,6 @@
flutter.isWidgetExpression(parent2.expression)) {
namedExp = parent2;
} else {
- _coverageMarker();
return;
}
}
@@ -1245,14 +1208,12 @@
var widgetClass = node.thisOrAncestorOfType<ClassDeclaration>();
var superclass = widgetClass?.extendsClause?.superclass;
if (widgetClass == null || superclass == null) {
- _coverageMarker();
return;
}
// Don't spam, activate only from the `class` keyword to the class body.
if (selectionOffset < widgetClass.classKeyword.offset ||
selectionOffset > widgetClass.leftBracket.end) {
- _coverageMarker();
return;
}
@@ -1268,14 +1229,12 @@
}
}
if (buildMethod == null) {
- _coverageMarker();
return;
}
// Must be a StatelessWidget subclasses.
var widgetClassElement = widgetClass.declaredElement;
if (!flutter.isExactlyStatelessWidgetType(widgetClassElement.supertype)) {
- _coverageMarker();
return;
}
@@ -1632,14 +1591,12 @@
Future<void> _addProposal_flutterSwapWithChild() async {
var parent = flutter.identifyNewExpression(node);
if (!flutter.isWidgetCreation(parent)) {
- _coverageMarker();
return;
}
var childArgument = flutter.findChildArgument(parent);
if (childArgument?.expression is! InstanceCreationExpression ||
!flutter.isWidgetCreation(childArgument.expression)) {
- _coverageMarker();
return;
}
InstanceCreationExpression child = childArgument.expression;
@@ -1651,14 +1608,12 @@
Future<void> _addProposal_flutterSwapWithParent() async {
var child = flutter.identifyNewExpression(node);
if (!flutter.isWidgetCreation(child)) {
- _coverageMarker();
return;
}
// NamedExpression (child:), ArgumentList, InstanceCreationExpression
var expr = child.parent?.parent?.parent;
if (expr is! InstanceCreationExpression) {
- _coverageMarker();
return;
}
InstanceCreationExpression parent = expr;
@@ -1759,11 +1714,9 @@
List<String> leadingLines = const []}) async {
var widgetExpr = flutter.identifyWidgetExpression(node);
if (widgetExpr == null) {
- _coverageMarker();
return;
}
if (widgetValidator != null && !widgetValidator(widgetExpr)) {
- _coverageMarker();
return;
}
var widgetSrc = utils.getNodeText(widgetExpr);
@@ -1903,18 +1856,15 @@
// prepare ImportDirective
var importDirective = node.thisOrAncestorOfType<ImportDirective>();
if (importDirective == null) {
- _coverageMarker();
return;
}
// there should be no existing combinators
if (importDirective.combinators.isNotEmpty) {
- _coverageMarker();
return;
}
// prepare whole import namespace
ImportElement importElement = importDirective.element;
if (importElement == null) {
- _coverageMarker();
return;
}
var namespace = getImportNamespace(importElement);
@@ -1932,7 +1882,6 @@
context.resolveResult.unit.accept(visitor);
// ignore if unused
if (referencedNames.isEmpty) {
- _coverageMarker();
return;
}
var changeBuilder = _newDartChangeBuilder();
@@ -1952,7 +1901,6 @@
}
// prepare IsExpression
if (node is! IsExpression) {
- _coverageMarker();
return;
}
IsExpression isExpression = node;
@@ -1969,7 +1917,6 @@
} else if (statement is WhileStatement && statement.body is Block) {
targetBlock = statement.body;
} else {
- _coverageMarker();
return;
}
prefix = utils.getNodePrefix(statement);
@@ -2048,24 +1995,20 @@
}
// prepare target "if" statement
if (node is! IfStatement) {
- _coverageMarker();
return;
}
var targetIfStatement = node as IfStatement;
if (targetIfStatement.elseStatement != null) {
- _coverageMarker();
return;
}
// prepare inner "if" statement
var targetThenStatement = targetIfStatement.thenStatement;
var innerStatement = getSingleStatement(targetThenStatement);
if (innerStatement is! IfStatement) {
- _coverageMarker();
return;
}
var innerIfStatement = innerStatement as IfStatement;
if (innerIfStatement.elseStatement != null) {
- _coverageMarker();
return;
}
// prepare environment
@@ -2108,30 +2051,25 @@
}
// prepare target "if" statement
if (node is! IfStatement) {
- _coverageMarker();
return;
}
var targetIfStatement = node as IfStatement;
if (targetIfStatement.elseStatement != null) {
- _coverageMarker();
return;
}
// prepare outer "if" statement
var parent = targetIfStatement.parent;
if (parent is Block) {
if ((parent as Block).statements.length != 1) {
- _coverageMarker();
return;
}
parent = parent.parent;
}
if (parent is! IfStatement) {
- _coverageMarker();
return;
}
var outerIfStatement = parent as IfStatement;
if (outerIfStatement.elseStatement != null) {
- _coverageMarker();
return;
}
// prepare environment
@@ -2170,19 +2108,16 @@
(node.parent as AssignmentExpression).leftHandSide == node &&
node.parent.parent is ExpressionStatement) {
} else {
- _coverageMarker();
return;
}
var assignExpression = node.parent as AssignmentExpression;
// check that binary expression is assignment
if (assignExpression.operator.type != TokenType.EQ) {
- _coverageMarker();
return;
}
// prepare "declaration" statement
var element = (node as SimpleIdentifier).staticElement;
if (element == null) {
- _coverageMarker();
return;
}
var declOffset = element.nameOffset;
@@ -2194,19 +2129,16 @@
declNode.parent.parent is VariableDeclarationList &&
declNode.parent.parent.parent is VariableDeclarationStatement) {
} else {
- _coverageMarker();
return;
}
var decl = declNode.parent as VariableDeclaration;
var declStatement = decl.parent.parent as VariableDeclarationStatement;
// may be has initializer
if (decl.initializer != null) {
- _coverageMarker();
return;
}
// check that "declaration" statement declared only one variable
if (declStatement.variables.variables.length != 1) {
- _coverageMarker();
return;
}
// check that the "declaration" and "assignment" statements are
@@ -2215,7 +2147,6 @@
if (assignStatement.parent is Block &&
assignStatement.parent == declStatement.parent) {
} else {
- _coverageMarker();
return;
}
var block = assignStatement.parent as Block;
@@ -2224,7 +2155,6 @@
if (statements.indexOf(assignStatement) ==
statements.indexOf(declStatement) + 1) {
} else {
- _coverageMarker();
return;
}
@@ -2242,20 +2172,17 @@
var declList = node.thisOrAncestorOfType<VariableDeclarationList>();
if (declList != null && declList.variables.length == 1) {
} else {
- _coverageMarker();
return;
}
var decl = declList.variables[0];
// already initialized
if (decl.initializer != null) {
- _coverageMarker();
return;
}
// prepare VariableDeclarationStatement in Block
if (declList.parent is VariableDeclarationStatement &&
declList.parent.parent is Block) {
} else {
- _coverageMarker();
return;
}
var declStatement = declList.parent as VariableDeclarationStatement;
@@ -2268,28 +2195,24 @@
var declIndex = statements.indexOf(declStatement);
if (declIndex < statements.length - 1) {
} else {
- _coverageMarker();
return;
}
// next Statement should be assignment
var assignStatement = statements[declIndex + 1];
if (assignStatement is ExpressionStatement) {
} else {
- _coverageMarker();
return;
}
var expressionStatement = assignStatement as ExpressionStatement;
// expression should be assignment
if (expressionStatement.expression is AssignmentExpression) {
} else {
- _coverageMarker();
return;
}
assignExpression = expressionStatement.expression as AssignmentExpression;
}
// check that pure assignment
if (assignExpression.operator.type != TokenType.EQ) {
- _coverageMarker();
return;
}
@@ -2309,13 +2232,11 @@
if ((node as ListLiteral).elements.any((CollectionElement exp) =>
!(exp is InstanceCreationExpression &&
flutter.isWidgetCreation(exp)))) {
- _coverageMarker();
return;
}
var literalSrc = utils.getNodeText(node);
var newlineIdx = literalSrc.lastIndexOf(eol);
if (newlineIdx < 0 || newlineIdx == literalSrc.length - 1) {
- _coverageMarker();
return; // Lists need to be in multi-line format already.
}
var indentOld = utils.getLinePrefix(node.offset + 1 + newlineIdx);
@@ -2353,7 +2274,6 @@
// may be on Statement with Conditional
var statement = node.thisOrAncestorOfType<Statement>();
if (statement == null) {
- _coverageMarker();
return;
}
// variable declaration
@@ -2451,7 +2371,6 @@
Future<void> _addProposal_replaceIfElseWithConditional() async {
// should be "if"
if (node is! IfStatement) {
- _coverageMarker();
return;
}
var ifStatement = node as IfStatement;
@@ -2459,7 +2378,6 @@
var thenStatement = getSingleStatement(ifStatement.thenStatement);
var elseStatement = getSingleStatement(ifStatement.elseStatement);
if (thenStatement == null || elseStatement == null) {
- _coverageMarker();
return;
}
Expression thenExpression;
@@ -2897,7 +2815,6 @@
InstanceCreationExpression child, AssistKind kind) async {
// The child must have its own child.
if (flutter.findChildArgument(child) == null) {
- _coverageMarker();
return;
}
@@ -2973,13 +2890,6 @@
_addAssistFromBuilder(changeBuilder, kind);
}
- /// This method does nothing, but we invoke it in places where Dart VM
- /// coverage agent fails to provide coverage information - such as almost
- /// all "return" statements.
- ///
- /// https://code.google.com/p/dart/issues/detail?id=19912
- static void _coverageMarker() {}
-
static String _replaceSourceIndent(
String source, String indentOld, String indentNew) {
return source.replaceAll(RegExp('^$indentOld', multiLine: true), indentNew);
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_required_keyword.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_required_keyword.dart
new file mode 100644
index 0000000..f844c86
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_required_keyword.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+
+class AddRequiredKeyword extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.ADD_REQUIRED2;
+
+ @override
+ Future<void> compute(DartChangeBuilder builder) async {
+ await builder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addSimpleInsertion(node.parent.offset, 'required ');
+ });
+ }
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index 68563e5..8411deb 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -174,6 +174,8 @@
FixKind('dart.fix.add.override', 50, "Add '@override' annotation");
static const ADD_REQUIRED =
FixKind('dart.fix.add.required', 50, "Add '@required' annotation");
+ static const ADD_REQUIRED2 =
+ FixKind('dart.fix.add.required', 50, "Add 'required' keyword");
static const ADD_RETURN_TYPE =
FixKind('dart.fix.add.returnType', 50, 'Add return type');
static const ADD_STATIC =
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index b2b500d..71cc015 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -14,6 +14,7 @@
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
import 'package:analysis_server/src/services/correction/dart/add_diagnostic_property_reference.dart';
import 'package:analysis_server/src/services/correction/dart/add_field_formal_parameters.dart';
+import 'package:analysis_server/src/services/correction/dart/add_required_keyword.dart';
import 'package:analysis_server/src/services/correction/dart/add_return_type.dart';
import 'package:analysis_server/src/services/correction/dart/add_type_annotation.dart';
import 'package:analysis_server/src/services/correction/dart/convert_add_all_to_spread.dart';
@@ -4371,6 +4372,9 @@
} else if (errorCode == HintCode.UNUSED_LOCAL_VARIABLE) {
await compute(RemoveUnusedLocalVariable());
} else if (errorCode ==
+ CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER) {
+ await compute(AddRequiredKeyword());
+ } else if (errorCode ==
CompileTimeErrorCode.NULLABLE_TYPE_IN_EXTENDS_CLAUSE) {
await compute(RemoveQuestionMark());
} else if (errorCode ==
diff --git a/pkg/analysis_server/test/domain_edit_dartfix_test.dart b/pkg/analysis_server/test/domain_edit_dartfix_test.dart
index 70b8662..69a64aa 100644
--- a/pkg/analysis_server/test/domain_edit_dartfix_test.dart
+++ b/pkg/analysis_server/test/domain_edit_dartfix_test.dart
@@ -187,7 +187,7 @@
expect(result.edits, hasLength(1));
expectFileEdits(originalContent, result.edits[0], '''
environment:
- sdk: '>=2.8.0 <3.0.0'
+ sdk: '>=2.9.0 <2.10.0'
name: foo
''');
@@ -209,7 +209,7 @@
name: foo
environment:
x: y
- sdk: '>=2.8.0 <3.0.0'
+ sdk: '>=2.9.0 <2.10.0'
''');
}
@@ -217,7 +217,7 @@
var originalContent = '''
name: foo
environment:
- sdk: '>=2.8.0 <3.0.0'
+ sdk: '>=2.9.0 <2.10.0'
''';
newFile('/project/pubspec.yaml', content: originalContent);
createProject();
@@ -242,7 +242,7 @@
expectFileEdits(originalContent, result.edits[0], '''
name: foo
environment:
- sdk: '>=2.8.0 <3.0.0'
+ sdk: '>=2.9.0 <2.10.0'
''');
}
diff --git a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
index c9bb123..3f94e1f 100644
--- a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
@@ -2192,7 +2192,7 @@
class MyClass {}
$docLines
-class MyClassTypeAlias = Object with MyClass;
+class MyMixinApplication = Object with MyClass;
$docLines
enum MyEnum {A, B, C}
@@ -2211,7 +2211,7 @@
assertDoc(suggestion);
}
{
- var suggestion = assertSuggestClassTypeAlias('MyClassTypeAlias');
+ var suggestion = assertSuggestClass('MyMixinApplication');
assertDoc(suggestion);
}
{
@@ -2494,7 +2494,7 @@
assertSuggestMethod('bar', 'C', 'void',
relevance: DART_RELEVANCE_LOCAL_METHOD);
assertSuggestFunctionTypeAlias('F2', 'int');
- assertSuggestClassTypeAlias('Clz');
+ assertSuggestClass('Clz');
assertSuggestClass('C');
assertNotSuggested('x');
assertNotSuggested('_B');
diff --git a/pkg/analysis_server/test/services/completion/dart/override_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/override_contributor_test.dart
index 9fd7549..d0df1f8 100644
--- a/pkg/analysis_server/test/services/completion/dart/override_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/override_contributor_test.dart
@@ -225,6 +225,110 @@
}''', displayText: 'foo() { … }', selectionOffset: 51, selectionLength: 0);
}
+ Future<void> test_inComment() async {
+ addTestSource('''
+class A {
+ void foo() {}
+}
+
+class B implements A {
+ // comment^
+ void m() {}
+}
+''');
+ await computeSuggestions();
+ _assertNoOverrideContaining('foo');
+ }
+
+ Future<void> test_inComment_dartdoc() async {
+ addTestSource('''
+class A {
+ void foo() {}
+}
+
+class B implements A {
+ /// dartdoc^
+ void m() {}
+}
+''');
+ await computeSuggestions();
+ _assertNoOverrideContaining('foo');
+ }
+
+ Future<void> test_inComment_reference() async {
+ addTestSource('''
+class A {
+ void foo() {}
+}
+
+class B implements A {
+ /// Asdf [St^]
+ void m() {}
+}
+''');
+ await computeSuggestions();
+ _assertNoOverrideContaining('foo');
+ }
+
+ Future<void> test_inConstructor() async {
+ addTestSource('''
+class A {
+ void foo() {}
+}
+
+class B implements A {
+ var one;
+ B(this.^);
+}
+''');
+ await computeSuggestions();
+ _assertNoOverrideContaining('foo');
+ }
+
+ Future<void> test_inConstructor2() async {
+ addTestSource('''
+class A {
+ void foo() {}
+}
+
+class B implements A {
+ var one;
+ var two;
+ B(this.one, {this.^});
+}
+''');
+ await computeSuggestions();
+ _assertNoOverrideContaining('foo');
+ }
+
+ Future<void> test_inFieldDeclaration_name() async {
+ addTestSource('''
+class A {
+ void foo() {}
+}
+
+class B implements A {
+ final String ^type;
+}
+''');
+ await computeSuggestions();
+ _assertNoOverrideContaining('foo');
+ }
+
+ Future<void> test_inFieldDeclaration_value() async {
+ addTestSource('''
+class A {
+ void foo() {}
+}
+
+class B implements A {
+ final String type = '^';
+}
+''');
+ await computeSuggestions();
+ _assertNoOverrideContaining('foo');
+ }
+
Future<void> test_inMixin_of_interface() async {
addTestSource('''
class A {
@@ -285,69 +389,6 @@
selectionLength: 22);
}
- Future<void> test_no_target_inClass_of_interface() async {
- addTestSource('''
-class A {
- void foo() {}
-}
-
-class B implements A {
- ^
-}
-''');
- await computeSuggestions();
- _assertOverride('''
-@override
- void foo() {
- // TODO: implement foo
- }''', displayText: 'foo() { … }', selectionOffset: 51, selectionLength: 0);
- }
-
- Future<void> test_no_target_inComment() async {
- addTestSource('''
-class A {
- void foo() {}
-}
-
-class B implements A {
- // comment ^
- void m() {}
-}
-''');
- await computeSuggestions();
- _assertNoOverrideContaining('foo');
- }
-
- Future<void> test_no_target_inComment2() async {
- addTestSource('''
-class A {
- void foo() {}
-}
-
-class B implements A {
- /// dartdoc ^
- void m() {}
-}
-''');
- await computeSuggestions();
- _assertNoOverrideContaining('foo');
- }
-
- Future<void> test_no_target_inComment3() async {
- addTestSource('''
-class A {
- void foo() {}
-}
-
-class B implements A {
- /// Asdf [St^]
- void m() {}
-}
-''');
- await computeSuggestions();
- _assertNoOverrideContaining('foo');
- }
-
Future<void> test_outsideOfWorkspace() async {
testFile = convertPath('/home/other/lib/a.dart');
addTestSource('''
diff --git a/pkg/analysis_server/test/services/completion/dart/relevance/instance_member_relevance_test.dart b/pkg/analysis_server/test/services/completion/dart/relevance/instance_member_relevance_test.dart
index a456ad4..cb7fff9 100644
--- a/pkg/analysis_server/test/services/completion/dart/relevance/instance_member_relevance_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/relevance/instance_member_relevance_test.dart
@@ -30,12 +30,29 @@
var length = suggestions.length;
expect(length, greaterThan(1),
reason: 'Test must specify more than one suggestion');
+ var inOrder = true;
var previous = suggestions[0];
for (var i = 1; i < length; i++) {
var current = suggestions[i];
- expect(current.relevance, lessThan(previous.relevance));
+ if (current.relevance >= previous.relevance) {
+ inOrder = false;
+ }
previous = current;
}
+ if (!inOrder) {
+ suggestions.sort((first, second) => second.relevance - first.relevance);
+ var buffer = StringBuffer();
+ buffer.writeln('Actual sort order does not match expected order.');
+ buffer.writeln('To accept the actual sort order, use:');
+ buffer.writeln();
+ buffer.writeln(' assertOrder([');
+ for (var suggestion in suggestions) {
+ var completion = suggestion.completion;
+ buffer.writeln(" suggestionWith(completion: '$completion'),");
+ }
+ buffer.writeln(' ]);');
+ fail(buffer.toString());
+ }
}
Future<void> test_contextType() async {
@@ -65,6 +82,27 @@
]);
}
+ Future<void> test_elementKind() async {
+ await addTestFile('''
+class A {
+ int get g => 0;
+ void m() { }
+ set s(int x) {}
+}
+
+void f(A a) {
+ a.^
+}
+''');
+ // The order below is dependent on generated data, so it can validly change
+ // when the data is re-generated.
+ assertOrder([
+ suggestionWith(completion: 'g'),
+ suggestionWith(completion: 's'),
+ suggestionWith(completion: 'm'),
+ ]);
+ }
+
Future<void> test_hasDeprecated() async {
await addTestFile('''
class C {
@@ -100,7 +138,7 @@
assertOrder([
suggestionWith(completion: 'b'),
suggestionWith(completion: 'a'),
- suggestionWith(completion: 'hashCode'),
+ suggestionWith(completion: 'toString'),
]);
}
diff --git a/pkg/analysis_server/test/src/cider/cider_service.dart b/pkg/analysis_server/test/src/cider/cider_service.dart
index e2c8bb1..b08f2f2 100644
--- a/pkg/analysis_server/test/src/cider/cider_service.dart
+++ b/pkg/analysis_server/test/src/cider/cider_service.dart
@@ -43,6 +43,7 @@
(String path) => _getDigest(path),
null,
workspace: workspace,
+ libraryContextResetTimeout: null,
);
fileResolver.testView = FileResolverTestView();
}
diff --git a/pkg/analysis_server/test/src/cider/fixes_test.dart b/pkg/analysis_server/test/src/cider/fixes_test.dart
new file mode 100644
index 0000000..b9157d5
--- /dev/null
+++ b/pkg/analysis_server/test/src/cider/fixes_test.dart
@@ -0,0 +1,121 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/plugin/edit/fix/fix_core.dart';
+import 'package:analysis_server/src/cider/fixes.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/source/line_info.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart' show SourceEdit;
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'cider_service.dart';
+
+void main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(CiderFixesComputerTest);
+ });
+}
+
+@reflectiveTest
+class CiderFixesComputerTest extends CiderServiceTest {
+ _CorrectionContext _correctionContext;
+ List<CiderErrorFixes> _errorsFixes;
+
+ void assertHasFix(FixKind kind, String expected) {
+ var fix = _getFix(kind);
+
+ var fileEdits = fix.change.edits;
+ expect(fileEdits, hasLength(1));
+
+ var resultContent = SourceEdit.applySequence(
+ _correctionContext.content,
+ fileEdits.single.edits,
+ );
+ expect(resultContent, expected);
+ }
+
+ Future<void> test_createMethod() async {
+ await _compute(r'''
+class A {
+}
+
+void f(A a) {
+ a.foo(0);^
+}
+''');
+
+ assertHasFix(DartFixKind.CREATE_METHOD, r'''
+class A {
+ void foo(int i) {}
+}
+
+void f(A a) {
+ a.foo(0);
+}
+''');
+ }
+
+ Future<void> test_insertSemicolon() async {
+ await _compute(r'''
+var v = 0^
+''');
+
+ assertHasFix(DartFixKind.INSERT_SEMICOLON, r'''
+var v = 0;
+''');
+ }
+
+ Future<void> _compute(String content) async {
+ _updateFile(content);
+
+ _errorsFixes = await CiderFixesComputer(
+ logger,
+ fileResolver,
+ ).compute(
+ convertPath(testPath),
+ _correctionContext.offset,
+ );
+ }
+
+ Fix _getFix(FixKind kind) {
+ for (var errorFixes in _errorsFixes) {
+ for (var fix in errorFixes.fixes) {
+ if (fix.kind == kind) {
+ return fix;
+ }
+ }
+ }
+ fail('No fix $kind');
+ }
+
+ void _updateFile(String content) {
+ var offset = content.indexOf('^');
+ expect(offset, isPositive, reason: 'Expected to find ^');
+ expect(content.indexOf('^', offset + 1), -1, reason: 'Expected only one ^');
+
+ var lineInfo = LineInfo.fromContent(content);
+ var location = lineInfo.getLocation(offset);
+
+ content = content.substring(0, offset) + content.substring(offset + 1);
+ newFile(testPath, content: content);
+
+ _correctionContext = _CorrectionContext(
+ content,
+ offset,
+ location.lineNumber - 1,
+ location.columnNumber - 1,
+ );
+ }
+}
+
+class _CorrectionContext {
+ final String content;
+ final int offset;
+ final int line;
+ final int character;
+
+ _CorrectionContext(this.content, this.offset, this.line, this.character);
+}
diff --git a/pkg/analysis_server/test/src/cider/test_all.dart b/pkg/analysis_server/test/src/cider/test_all.dart
index dfae1ef..9aea1f0 100644
--- a/pkg/analysis_server/test/src/cider/test_all.dart
+++ b/pkg/analysis_server/test/src/cider/test_all.dart
@@ -1,13 +1,15 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'completion_test.dart' as completion;
+import 'fixes_test.dart' as fixes;
void main() {
defineReflectiveSuite(() {
completion.main();
+ fixes.main();
});
}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_required_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_required_test.dart
index b9ecdf2..14fdb0d 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_required_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_required_test.dart
@@ -12,6 +12,7 @@
void main() {
defineReflectiveSuite(() {
defineReflectiveTests(AddRequiredTest);
+ defineReflectiveTests(AddRequiredWithNNBDTest);
});
}
@@ -36,3 +37,21 @@
''');
}
}
+
+@reflectiveTest
+class AddRequiredWithNNBDTest extends FixProcessorTest {
+ @override
+ List<String> get experiments => ['non-nullable'];
+
+ @override
+ FixKind get kind => DartFixKind.ADD_REQUIRED2;
+
+ Future<void> test_withAssert() async {
+ await resolveTestUnit('''
+void function({String param}) {}
+''');
+ await assertHasFix('''
+void function({required String param}) {}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart b/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart
index 1ed5b4a..4808f8b 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart
@@ -27,10 +27,6 @@
/// The offset of the lint marker in the code being analyzed.
int lintOffset = -1;
- /// Return a list of the experiments that are to be enabled for tests in this
- /// class, or `null` if there are no experiments that should be enabled.
- List<String> get experiments => null;
-
/// Return the lint code being tested.
String get lintCode;
@@ -41,8 +37,7 @@
}
@override
- void setUp() {
- super.setUp();
+ void _createAnalysisOptionsFile() {
createAnalysisOptionsFile(experiments: experiments, lints: [lintCode]);
}
@@ -75,6 +70,10 @@
/// neither [assertHasFix] nor [assertHasFixAllFix] has been invoked.
String resultCode;
+ /// Return a list of the experiments that are to be enabled for tests in this
+ /// class, or `null` if there are no experiments that should be enabled.
+ List<String> get experiments => null;
+
/// Return the kind of fixes being tested by this test class.
FixKind get kind;
@@ -172,6 +171,7 @@
void setUp() {
super.setUp();
verifyNoTestUnitErrors = false;
+ _createAnalysisOptionsFile();
}
/// Computes fixes and verifies that there is a fix for the given [error] of the appropriate kind.
@@ -293,6 +293,12 @@
return await DartFixContributor().computeFixes(context);
}
+ /// Create the analysis options file needed in order to correctly analyze the
+ /// test file.
+ void _createAnalysisOptionsFile() {
+ createAnalysisOptionsFile(experiments: experiments);
+ }
+
/// Find the error that is to be fixed by computing the errors in the file,
/// using the [errorFilter] to filter out errors that should be ignored, and
/// expecting that there is a single remaining error. The error filter should
diff --git a/pkg/analysis_server/tool/completion_metrics/completion_metrics.dart b/pkg/analysis_server/tool/completion_metrics/completion_metrics.dart
index 9fea6b2..38dcbeb 100644
--- a/pkg/analysis_server/tool/completion_metrics/completion_metrics.dart
+++ b/pkg/analysis_server/tool/completion_metrics/completion_metrics.dart
@@ -5,6 +5,7 @@
import 'dart:async';
import 'dart:io' as io;
+import 'package:analysis_server/src/domains/completion/available_suggestions.dart';
import 'package:analysis_server/src/protocol_server.dart';
import 'package:analysis_server/src/services/completion/completion_core.dart';
import 'package:analysis_server/src/services/completion/completion_performance.dart';
@@ -17,8 +18,11 @@
import 'package:analyzer/error/error.dart' as err;
import 'package:analyzer/file_system/overlay_file_system.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/src/dart/analysis/byte_store.dart';
import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
+import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart';
import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/services/available_declarations.dart';
import 'package:args/args.dart';
import 'metrics_util.dart';
@@ -37,7 +41,9 @@
print('Analyzing root: "$root"');
var stopwatch = Stopwatch()..start();
var code = await CompletionMetricsComputer(root,
- verbose: result['verbose'], overlay: result['overlay'])
+ verbose: result['verbose'],
+ availableSuggestions: result[AVAILABLE_SUGGESTIONS],
+ overlay: result[OVERLAY])
.compute();
stopwatch.stop();
@@ -47,6 +53,10 @@
return io.exit(code);
}
+const String AVAILABLE_SUGGESTIONS = 'available-suggestions';
+
+const String OVERLAY = 'overlay';
+
const String OVERLAY_NONE = 'none';
const String OVERLAY_REMOVE_REST_OF_FILE = 'remove-rest-of-file';
@@ -55,30 +65,39 @@
/// Create a parser that can be used to parse the command-line arguments.
ArgParser createArgParser() {
- var parser = ArgParser();
- parser.addOption(
- 'help',
- abbr: 'h',
- help: 'Print this help message.',
- );
- parser.addFlag(
- 'verbose',
- abbr: 'v',
- help: 'Print additional information about the analysis',
- negatable: false,
- );
- parser.addOption('overlay',
- allowed: [
- OVERLAY_NONE,
- OVERLAY_REMOVE_TOKEN,
- OVERLAY_REMOVE_REST_OF_FILE
- ],
- defaultsTo: OVERLAY_NONE,
- help: 'Before attempting a completion at the location of each token, the '
- 'token can be removed, or the rest of the file can be removed to test '
- 'code completion with diverse methods. The default mode is to '
- 'complete at the start of the token without modifying the file.');
- return parser;
+ return ArgParser()
+ ..addOption(
+ 'help',
+ abbr: 'h',
+ help: 'Print this help message.',
+ )
+ ..addFlag(
+ 'verbose',
+ abbr: 'v',
+ help: 'Print additional information about the analysis',
+ negatable: false,
+ )
+ ..addFlag(AVAILABLE_SUGGESTIONS,
+ abbr: 'a',
+ help: 'Use the available suggestions feature in the Analysis Server '
+ 'when computing the set of code completions. With this feature '
+ 'enabled, completion will match the support in the Dart Plugin for '
+ 'IntelliJ, without this enabled the completion support matches '
+ 'the support in LSP.',
+ defaultsTo: false,
+ negatable: false)
+ ..addOption(OVERLAY,
+ allowed: [
+ OVERLAY_NONE,
+ OVERLAY_REMOVE_TOKEN,
+ OVERLAY_REMOVE_REST_OF_FILE
+ ],
+ defaultsTo: OVERLAY_NONE,
+ help:
+ 'Before attempting a completion at the location of each token, the '
+ 'token can be removed, or the rest of the file can be removed to test '
+ 'code completion with diverse methods. The default mode is to '
+ 'complete at the start of the token without modifying the file.');
}
/// Print usage information for this tool.
@@ -115,6 +134,9 @@
/// A wrapper for the collection of [Counter] and [MeanReciprocalRankComputer]
/// objects for a run of [CompletionMetricsComputer].
class CompletionMetrics {
+ /// The maximum number of longest results to collect.
+ static const maxLongestResults = 10;
+
/// The maximum number of worst results to collect.
static const maxWorstResults = 10;
@@ -163,10 +185,16 @@
/// (worst) ranks.
List<CompletionResult> worstResults = [];
+ /// A list of the top [maxLongestResults] completion results with the highest
+ /// (worst) ranks.
+ List<CompletionResult> longestResults = [];
+
CompletionMetrics(this.name);
- /// If the [result] is worse than any previously recorded results, record it.
+ /// Record this completion result, this method handles the worst ranked items
+ /// as well as the longest sets of results to compute.
void recordCompletionResult(CompletionResult result) {
+ // If the [result] is worse than any previously recorded results, record it.
if (worstResults.length >= maxWorstResults) {
if (result.place.rank <= worstResults.last.place.rank) {
return;
@@ -175,6 +203,20 @@
}
worstResults.add(result);
worstResults.sort((first, second) => second.place.rank - first.place.rank);
+
+ // Record this elapsed ms count for the average ms count.
+ meanCompletionMS.addValue(result.elapsedMS);
+
+ // If the [result] is took longer than any previously recorded results,
+ // record it.
+ if (longestResults.length >= maxLongestResults) {
+ if (result.elapsedMS <= longestResults.last.elapsedMS) {
+ return;
+ }
+ longestResults.removeLast();
+ }
+ longestResults.add(result);
+ longestResults.sort((first, second) => second.elapsedMS - first.elapsedMS);
}
}
@@ -186,6 +228,8 @@
final bool verbose;
+ final bool availableSuggestions;
+
final String overlay;
ResolvedUnitResult _resolvedUnitResult;
@@ -202,7 +246,8 @@
int overlayModificationStamp = 0;
- CompletionMetricsComputer(this.rootPath, {this.verbose, this.overlay})
+ CompletionMetricsComputer(this.rootPath,
+ {this.verbose, this.availableSuggestions, this.overlay})
: assert(overlay == OVERLAY_NONE ||
overlay == OVERLAY_REMOVE_TOKEN ||
overlay == OVERLAY_REMOVE_REST_OF_FILE);
@@ -222,6 +267,7 @@
printMetrics(metricsNewMode);
if (verbose) {
printWorstResults(metricsNewMode);
+ printLongestResults(metricsNewMode);
}
return resultCode;
}
@@ -230,6 +276,7 @@
ExpectedCompletion expectedCompletion,
List<CompletionSuggestion> suggestions,
CompletionMetrics metrics,
+ int elapsedMS,
bool doPrintMissedCompletions) {
assert(suggestions != null);
@@ -246,7 +293,7 @@
metrics.completionCounter.count('successful');
metrics.recordCompletionResult(
- CompletionResult(place, suggestions, expectedCompletion));
+ CompletionResult(place, suggestions, expectedCompletion, elapsedMS));
var element = getElement(expectedCompletion.syntacticEntity);
if (isInstanceMember(element)) {
@@ -294,6 +341,22 @@
return successfulCompletion;
}
+ void printLongestResults(CompletionMetrics metrics) {
+ print('');
+ print('====================');
+ print('The longest completion results to compute:');
+ for (var result in metrics.longestResults) {
+ var elapsedMS = result.elapsedMS;
+ var expected = result.expectedCompletion;
+ print('');
+ print('Elapsed ms: $elapsedMS');
+ print('Completion: ${expected.completion}');
+ print('Completion kind: ${expected.kind}');
+ print('Element kind: ${expected.elementKind}');
+ print('Location: ${expected.location}');
+ }
+ }
+
void printMetrics(CompletionMetrics metrics) {
print('');
print('');
@@ -356,7 +419,7 @@
print('Completion: ${expected.completion}');
print('Completion kind: ${expected.kind}');
print('Element kind: ${expected.elementKind}');
- print('Offset: ${expected.offset}');
+ print('Location: ${expected.location}');
print('Preceeding: $preceeding');
print('Suggestion: ${suggestions[rank - 1]}');
}
@@ -385,44 +448,83 @@
ResolvedUnitResult resolvedUnitResult,
int offset,
CompletionMetrics metrics,
- [bool useNewRelevance = false]) async {
- var completionRequestImpl = CompletionRequestImpl(
+ [bool useNewRelevance = false,
+ DeclarationsTracker declarationsTracker,
+ CompletionAvailableSuggestionsParams availableSuggestionsParams]) async {
+ var completionRequest = CompletionRequestImpl(
resolvedUnitResult,
offset,
useNewRelevance,
CompletionPerformance(),
);
- var stopwatch = Stopwatch()..start();
+ var suggestions;
- // This gets all of the suggestions with relevances.
- var suggestions =
- await DartCompletionManager().computeSuggestions(completionRequestImpl);
+ if (declarationsTracker == null) {
+ // available suggestions == false
+ suggestions = await DartCompletionManager(
+ dartdocDirectiveInfo: DartdocDirectiveInfo())
+ .computeSuggestions(completionRequest);
+ } else {
+ // available suggestions == true
+ var includedElementKinds = <ElementKind>{};
+ var includedElementNames = <String>{};
+ var includedSuggestionRelevanceTagList =
+ <IncludedSuggestionRelevanceTag>[];
+ var includedSuggestionSetList = <IncludedSuggestionSet>[];
+ suggestions = await DartCompletionManager(
+ dartdocDirectiveInfo: DartdocDirectiveInfo(),
+ includedElementKinds: includedElementKinds,
+ includedElementNames: includedElementNames,
+ includedSuggestionRelevanceTags:
+ includedSuggestionRelevanceTagList)
+ .computeSuggestions(completionRequest);
-// // If a non-null declarationsTracker was passed, use it to call
-// // computeIncludedSetList, this current implementation just adds the set of
-// // included element names with relevance 0, future implementations should
-// // compute out the relevance that clients will set to each value.
-// if (declarationsTracker != null) {
-// var includedSuggestionSets = <IncludedSuggestionSet>[];
-// var includedElementNames = <String>{};
-//
-// computeIncludedSetList(declarationsTracker, resolvedUnitResult,
-// includedSuggestionSets, includedElementNames);
-//
-// for (var eltName in includedElementNames) {
-// suggestions.add(CompletionSuggestion(
-// CompletionSuggestionKind.INVOCATION,
-// 0,
-// eltName,
-// 0,
-// eltName.length,
-// false,
-// false));
-// }
-// }
- stopwatch.stop();
- metrics.meanCompletionMS.addValue(stopwatch.elapsedMilliseconds);
+ computeIncludedSetList(declarationsTracker, resolvedUnitResult,
+ includedSuggestionSetList, includedElementNames);
+
+ var includedSuggestionSetMap = {
+ for (var includedSuggestionSet in includedSuggestionSetList)
+ includedSuggestionSet.id: includedSuggestionSet,
+ };
+
+ var includedSuggestionRelevanceTagMap = {
+ for (var includedSuggestionRelevanceTag
+ in includedSuggestionRelevanceTagList)
+ includedSuggestionRelevanceTag.tag:
+ includedSuggestionRelevanceTag.relevanceBoost,
+ };
+
+ for (var availableSuggestionSet
+ in availableSuggestionsParams.changedLibraries) {
+ var id = availableSuggestionSet.id;
+ for (var availableSuggestion in availableSuggestionSet.items) {
+ // Exclude available suggestions where this element kind doesn't match
+ // an element kind in includedElementKinds.
+ var elementKind = availableSuggestion.element?.kind;
+ if (elementKind != null &&
+ includedElementKinds.contains(elementKind)) {
+ if (includedSuggestionSetMap.containsKey(id)) {
+ var relevance = includedSuggestionSetMap[id].relevance;
+
+ // Search for any matching relevance tags to apply any boosts
+ if (includedSuggestionRelevanceTagList.isNotEmpty &&
+ availableSuggestion.relevanceTags != null &&
+ availableSuggestion.relevanceTags.isNotEmpty) {
+ for (var tag in availableSuggestion.relevanceTags) {
+ if (includedSuggestionRelevanceTagMap.containsKey(tag)) {
+ // apply the boost
+ relevance += includedSuggestionRelevanceTagMap[tag];
+ }
+ }
+ }
+ suggestions
+ .add(availableSuggestion.toCompletionSuggestion(relevance));
+ }
+ }
+ }
+ }
+ }
suggestions.sort(completionComparator);
return suggestions;
@@ -433,8 +535,6 @@
/// should be captured in the [collector].
Future<void> _computeInContext(ContextRoot root) async {
// Create a new collection to avoid consuming large quantities of memory.
- // TODO(brianwilkerson) Create an OverlayResourceProvider to allow the
- // content of the files to be modified before computing suggestions.
final collection = AnalysisContextCollection(
includedPaths: root.includedPaths.toList(),
excludedPaths: root.excludedPaths.toList(),
@@ -442,16 +542,28 @@
);
var context = collection.contexts[0];
-// // Set the DeclarationsTracker, only call doWork to build up the available
-// // suggestions if doComputeCompletionsFromAnalysisServer is true.
-// // TODO(brianwilkerson) Add a flag to control whether available suggestions
-// // are to be used.
-// var declarationsTracker = DeclarationsTracker(
-// MemoryByteStore(), PhysicalResourceProvider.INSTANCE);
-// declarationsTracker.addContext(context);
-// while (declarationsTracker.hasWork) {
-// declarationsTracker.doWork();
-// }
+
+ // Set the DeclarationsTracker, only call doWork to build up the available
+ // suggestions if doComputeCompletionsFromAnalysisServer is true.
+ var declarationsTracker;
+ var availableSuggestionsParams;
+ if (availableSuggestions) {
+ declarationsTracker = DeclarationsTracker(
+ MemoryByteStore(), PhysicalResourceProvider.INSTANCE);
+ declarationsTracker.addContext(context);
+ while (declarationsTracker.hasWork) {
+ declarationsTracker.doWork();
+ }
+
+ // Have the AvailableDeclarationsSet computed to use later.
+ availableSuggestionsParams = createCompletionAvailableSuggestions(
+ declarationsTracker.allLibraries.toList(), []);
+
+ // assert that this object is not null, throw if it is.
+ if (availableSuggestionsParams == null) {
+ throw Exception('availableSuggestionsParam not computable.');
+ }
+ }
// Loop through each file, resolve the file and call
// forEachExpectedCompletion
@@ -500,24 +612,40 @@
// First we compute the completions useNewRelevance set to
// false:
+ var stopwatch = Stopwatch()..start();
var suggestions = await _computeCompletionSuggestions(
resolvedUnitResultWithOverlay,
expectedCompletion.offset,
metricsOldMode,
- false);
+ false,
+ declarationsTracker,
+ availableSuggestionsParams);
+ stopwatch.stop();
var successfulnessUseOldRelevance = forEachExpectedCompletion(
- expectedCompletion, suggestions, metricsOldMode, false);
+ expectedCompletion,
+ suggestions,
+ metricsOldMode,
+ stopwatch.elapsedMilliseconds,
+ false);
// And again here with useNewRelevance set to true:
+ stopwatch = Stopwatch()..start();
suggestions = await _computeCompletionSuggestions(
resolvedUnitResultWithOverlay,
expectedCompletion.offset,
metricsNewMode,
- true);
+ true,
+ declarationsTracker,
+ availableSuggestionsParams);
+ stopwatch.stop();
var successfulnessUseNewRelevance = forEachExpectedCompletion(
- expectedCompletion, suggestions, metricsNewMode, verbose);
+ expectedCompletion,
+ suggestions,
+ metricsNewMode,
+ stopwatch.elapsedMilliseconds,
+ verbose);
if (verbose &&
successfulnessUseOldRelevance !=
@@ -614,5 +742,17 @@
final ExpectedCompletion expectedCompletion;
- CompletionResult(this.place, this.suggestions, this.expectedCompletion);
+ final int elapsedMS;
+
+ CompletionResult(
+ this.place, this.suggestions, this.expectedCompletion, this.elapsedMS);
+}
+
+extension AvailableSuggestionsExtension on AvailableSuggestion {
+ // TODO(jwren) I am not sure if we want CompletionSuggestionKind.INVOCATION in
+ // call cases here, to iterate I need to figure out why this algorithm is
+ // taking so much time.
+ CompletionSuggestion toCompletionSuggestion(int relevance) =>
+ CompletionSuggestion(CompletionSuggestionKind.INVOCATION, relevance,
+ label, label.length, 0, element.isDeprecated, false);
}
diff --git a/pkg/analysis_server/tool/completion_metrics/visitors.dart b/pkg/analysis_server/tool/completion_metrics/visitors.dart
index 7bacd2c..f154a6d 100644
--- a/pkg/analysis_server/tool/completion_metrics/visitors.dart
+++ b/pkg/analysis_server/tool/completion_metrics/visitors.dart
@@ -47,10 +47,14 @@
protocol.ElementKind get elementKind => _elementKind;
+ String get filePath => _filePath;
+
protocol.CompletionSuggestionKind get kind => _kind;
int get lineNumber => _lineNumber;
+ String get location => '$filePath:$lineNumber:$columnNumber';
+
int get offset => _entity.offset;
SyntacticEntity get syntacticEntity => _entity;
@@ -74,7 +78,7 @@
@override
String toString() =>
- "'$completion', kind = $kind, elementKind = $elementKind, $_filePath:$lineNumber:$columnNumber";
+ "'$completion', kind = $kind, elementKind = $elementKind, $location";
}
class ExpectedCompletionsVisitor extends RecursiveAstVisitor<void> {
diff --git a/pkg/analysis_server_client/CHANGELOG.md b/pkg/analysis_server_client/CHANGELOG.md
index 144b255..43563a1 100644
--- a/pkg/analysis_server_client/CHANGELOG.md
+++ b/pkg/analysis_server_client/CHANGELOG.md
@@ -1,3 +1,7 @@
+# 1.1.3
+ * Supports changes made to the Analysis Server protocol through Dart 2.8.0
+ * Updates to use pedantic 1.9.0 and some internal refactoring.
+
# 1.1.2
* Update the dartfix protocol to include `--pedantic`
* Supports changes made to Analysis Server protocol through Dart 2.6.0
diff --git a/pkg/analysis_server_client/pubspec.yaml b/pkg/analysis_server_client/pubspec.yaml
index e661389..bc8b89f 100644
--- a/pkg/analysis_server_client/pubspec.yaml
+++ b/pkg/analysis_server_client/pubspec.yaml
@@ -6,9 +6,9 @@
and facilitate communication to and from the server.
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analysis_server_client
environment:
- sdk: '>=2.1.0-dev.9.0 <3.0.0'
+ sdk: '>=2.8.0 <3.0.0'
dependencies:
- path: ^1.6.2
- pub_semver: ^1.4.2
+ path: ^1.7.0
+ pub_semver: ^1.4.4
dev_dependencies:
- test: ^1.3.4
+ test: ^1.14.2
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index abb323f..0680d6b 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,6 +1,13 @@
-## 0.39.8-dev
+## 0.39.8
* Deprecated `VariableElement.constantValue`, it does not guarantee that
the value has been computed. Use `computeConstantValue()` instead.
+* Deprecated the following members of `AnalysisOptions`:
+ `analyzeFunctionBodiesPredicate`, `disableCacheFlushing`,
+ `enableLazyAssignmentOperators`, `generateImplicitErrors`,
+ `generateSdkErrors`, `patchPaths`, `preserveComments`,
+ `trackCacheDependencies`, and `resetToDefaults`.
+* Bug fixes: #35716, #37048, #40014, #40957, #41479, #41521, #41551, #41555,
+ #41557, #41593, #41603, #41630, #41632, #41645.
## 0.39.7
* Added new error codes: ENUM_CONSTANT_SAME_NAME_AS_ENCLOSING and
diff --git a/pkg/analyzer/lib/dart/analysis/features.dart b/pkg/analyzer/lib/dart/analysis/features.dart
index 561a4db..1d46e72 100644
--- a/pkg/analyzer/lib/dart/analysis/features.dart
+++ b/pkg/analyzer/lib/dart/analysis/features.dart
@@ -70,8 +70,8 @@
/// Queries whether the given [feature] is contained in this feature set.
bool isEnabled(Feature feature);
- /// Computes a subset of this FeatureSet by removing any features that weren't
- /// available in the given Dart SDK version.
+ /// Computes a subset of this FeatureSet by removing any features that are
+ /// not available in the given language version.
FeatureSet restrictToVersion(Version version);
}
@@ -82,7 +82,7 @@
future,
/// The language feature has not yet shipped, but we are testing the effect of
- /// enabling it by default. It may be used in any library with an appopriate
+ /// enabling it by default. It may be used in any library with an appropriate
/// version constraint, unless an experimental flag is used to disable it.
provisional,
diff --git a/pkg/analyzer/lib/src/dart/analysis/experiments_impl.dart b/pkg/analyzer/lib/src/dart/analysis/experiments_impl.dart
index 88c6582..ca5b993 100644
--- a/pkg/analyzer/lib/src/dart/analysis/experiments_impl.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/experiments_impl.dart
@@ -90,12 +90,16 @@
}
/// Computes a new set of enable flags based on [flags], but with any features
-/// that were not present in [version] set to `false`.
+/// that are not present in the language [version] set to `false`.
List<bool> restrictEnableFlagsToVersion(List<bool> flags, Version version) {
+ if (version == ExperimentStatus.currentVersion) {
+ return flags;
+ }
+
flags = List.from(flags);
for (var feature in _knownFeatures.values) {
- if (!feature.isEnabledByDefault ||
- feature.firstSupportedVersion > version) {
+ var firstSupportedVersion = feature.firstSupportedVersion;
+ if (firstSupportedVersion == null || firstSupportedVersion > version) {
flags[feature.index] = false;
}
}
diff --git a/pkg/analyzer/lib/src/dart/analysis/feature_set_provider.dart b/pkg/analyzer/lib/src/dart/analysis/feature_set_provider.dart
index ae462be..b02965c 100644
--- a/pkg/analyzer/lib/src/dart/analysis/feature_set_provider.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/feature_set_provider.dart
@@ -38,12 +38,8 @@
var package = _packages.packageForPath(path);
if (package != null) {
var languageVersion = package.languageVersion;
- if (languageVersion == null ||
- languageVersion == ExperimentStatus.currentVersion) {
- return _packageDefaultFeatureSet;
- } else {
- return _packageDefaultFeatureSet.restrictToVersion(languageVersion);
- }
+ languageVersion ??= ExperimentStatus.currentVersion;
+ return _packageDefaultFeatureSet.restrictToVersion(languageVersion);
}
return _nonPackageDefaultFeatureSet;
diff --git a/pkg/analyzer/lib/src/dart/analysis/index.dart b/pkg/analyzer/lib/src/dart/analysis/index.dart
index 0cb5728..89a1393 100644
--- a/pkg/analyzer/lib/src/dart/analysis/index.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/index.dart
@@ -445,7 +445,9 @@
element = element.enclosingElement;
}
if (element?.enclosingElement is CompilationUnitElement) {
- nameIdUnitMember = _getStringInfo(element.name);
+ // Unnamed extensions have a null `name`, but _StringInfo instances must
+ // have non-null values.
+ nameIdUnitMember = _getStringInfo(element.name ?? '');
}
return _ElementInfo(unitId, nameIdUnitMember, nameIdClassMember,
nameIdParameter, info.kind);
diff --git a/pkg/analyzer/lib/src/dart/analysis/session.dart b/pkg/analyzer/lib/src/dart/analysis/session.dart
index d34a7ce..e0a5320 100644
--- a/pkg/analyzer/lib/src/dart/analysis/session.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/session.dart
@@ -216,7 +216,7 @@
/// Data structure containing information about the analysis session that is
/// available synchronously.
class SynchronousSession {
- final AnalysisOptionsImpl analysisOptions;
+ AnalysisOptionsImpl _analysisOptions;
final DeclaredVariables declaredVariables;
@@ -228,7 +228,23 @@
InheritanceManager3 _inheritanceManager;
- SynchronousSession(this.analysisOptions, this.declaredVariables);
+ SynchronousSession(this._analysisOptions, this.declaredVariables);
+
+ AnalysisOptionsImpl get analysisOptions => _analysisOptions;
+
+ set analysisOptions(AnalysisOptionsImpl analysisOptions) {
+ this._analysisOptions = analysisOptions;
+
+ _typeSystemLegacy?.updateOptions(
+ implicitCasts: analysisOptions.implicitCasts,
+ strictInference: analysisOptions.strictInference,
+ );
+
+ _typeSystemNonNullableByDefault?.updateOptions(
+ implicitCasts: analysisOptions.implicitCasts,
+ strictInference: analysisOptions.strictInference,
+ );
+ }
InheritanceManager3 get inheritanceManager {
return _inheritanceManager ??= InheritanceManager3();
@@ -281,16 +297,16 @@
_typeProviderNonNullableByDefault = nonNullableByDefault;
_typeSystemLegacy = TypeSystemImpl(
- implicitCasts: analysisOptions.implicitCasts,
+ implicitCasts: _analysisOptions.implicitCasts,
isNonNullableByDefault: false,
- strictInference: analysisOptions.strictInference,
+ strictInference: _analysisOptions.strictInference,
typeProvider: _typeProviderLegacy,
);
_typeSystemNonNullableByDefault = TypeSystemImpl(
- implicitCasts: analysisOptions.implicitCasts,
+ implicitCasts: _analysisOptions.implicitCasts,
isNonNullableByDefault: true,
- strictInference: analysisOptions.strictInference,
+ strictInference: _analysisOptions.strictInference,
typeProvider: _typeProviderNonNullableByDefault,
);
}
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 5422092..5234c13 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -4072,7 +4072,7 @@
@override
String get name {
if (linkedNode != null) {
- return (linkedNode as ExtensionDeclaration).name?.name ?? '';
+ return (linkedNode as ExtensionDeclaration).name?.name;
}
return super.name;
}
diff --git a/pkg/analyzer/lib/src/dart/micro/analysis_context.dart b/pkg/analyzer/lib/src/dart/micro/analysis_context.dart
index a9d7cf3..82a6e42 100644
--- a/pkg/analyzer/lib/src/dart/micro/analysis_context.dart
+++ b/pkg/analyzer/lib/src/dart/micro/analysis_context.dart
@@ -5,53 +5,125 @@
import 'package:analyzer/dart/analysis/analysis_context.dart';
import 'package:analyzer/dart/analysis/context_root.dart';
import 'package:analyzer/dart/analysis/declared_variables.dart';
-import 'package:analyzer/dart/analysis/session.dart';
+import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/uri_converter.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/context/builder.dart';
-import 'package:analyzer/src/dart/analysis/session.dart';
-import 'package:analyzer/src/generated/engine.dart' show AnalysisOptions;
-import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/dart/analysis/context_root.dart';
import 'package:analyzer/src/dart/analysis/results.dart';
-import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/dart/analysis/session.dart';
import 'package:analyzer/src/dart/micro/resolve_file.dart';
+import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
+import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/workspace/workspace.dart';
+import 'package:meta/meta.dart';
-class MicroAnalysisContextImpl implements AnalysisContext {
+MicroContextObjects createMicroContextObjects({
+ @required FileResolver fileResolver,
+ @required AnalysisOptionsImpl analysisOptions,
+ @required SourceFactory sourceFactory,
+ @required ContextRootImpl root,
+ @required ResourceProvider resourceProvider,
+ @required Workspace workspace,
+}) {
+ var declaredVariables = DeclaredVariables();
+ var synchronousSession = SynchronousSession(
+ analysisOptions,
+ declaredVariables,
+ );
+
+ var analysisContext = AnalysisContextImpl(
+ synchronousSession,
+ sourceFactory,
+ );
+
+ var analysisSession = _MicroAnalysisSessionImpl(
+ declaredVariables,
+ sourceFactory,
+ );
+
+ var analysisContext2 = _MicroAnalysisContextImpl(
+ fileResolver,
+ synchronousSession,
+ root,
+ declaredVariables,
+ sourceFactory,
+ resourceProvider,
+ workspace: workspace,
+ );
+
+ analysisContext2.currentSession = analysisSession;
+ analysisSession.analysisContext = analysisContext2;
+
+ return MicroContextObjects(
+ declaredVariables: declaredVariables,
+ synchronousSession: synchronousSession,
+ analysisSession: analysisSession,
+ analysisContext: analysisContext,
+ analysisContext2: analysisContext2,
+ );
+}
+
+class MicroContextObjects {
+ final DeclaredVariables declaredVariables;
+ final SynchronousSession synchronousSession;
+ final _MicroAnalysisSessionImpl analysisSession;
+ final AnalysisContextImpl analysisContext;
+ final _MicroAnalysisContextImpl analysisContext2;
+
+ MicroContextObjects({
+ @required this.declaredVariables,
+ @required this.synchronousSession,
+ @required this.analysisSession,
+ @required this.analysisContext,
+ @required this.analysisContext2,
+ });
+
+ set analysisOptions(AnalysisOptionsImpl analysisOptions) {
+ synchronousSession.analysisOptions = analysisOptions;
+ }
+}
+
+class _MicroAnalysisContextImpl implements AnalysisContext {
final FileResolver fileResolver;
-
- @override
- final AnalysisOptions analysisOptions;
+ final SynchronousSession synchronousSession;
final ResourceProvider resourceProvider;
@override
final ContextRoot contextRoot;
+ @override
+ _MicroAnalysisSessionImpl currentSession;
+
final DeclaredVariables declaredVariables;
final SourceFactory sourceFactory;
Workspace _workspace;
+ _MicroAnalysisContextImpl(
+ this.fileResolver,
+ this.synchronousSession,
+ this.contextRoot,
+ this.declaredVariables,
+ this.sourceFactory,
+ this.resourceProvider, {
+ Workspace workspace,
+ }) : this._workspace = workspace;
+
+ @override
+ AnalysisOptionsImpl get analysisOptions {
+ return synchronousSession.analysisOptions;
+ }
+
@override
Workspace get workspace {
return _workspace ??= _buildWorkspace();
}
- MicroAnalysisContextImpl(
- this.fileResolver,
- this.contextRoot,
- this.analysisOptions,
- this.declaredVariables,
- this.sourceFactory,
- this.resourceProvider,
- {Workspace workspace})
- : this._workspace = workspace;
-
@override
- AnalysisSession get currentSession {
- return _AnalysisSessionImpl(this, declaredVariables, sourceFactory);
- }
+ noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
Workspace _buildWorkspace() {
String path = contextRoot.root.path;
@@ -59,14 +131,11 @@
resourceProvider, null /* sdkManager */, null /* contentCache */);
return ContextBuilder.createWorkspace(resourceProvider, path, builder);
}
-
- @override
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
-class _AnalysisSessionImpl extends AnalysisSessionImpl {
+class _MicroAnalysisSessionImpl extends AnalysisSessionImpl {
@override
- final MicroAnalysisContextImpl analysisContext;
+ _MicroAnalysisContextImpl analysisContext;
@override
final DeclaredVariables declaredVariables;
@@ -74,16 +143,24 @@
@override
SourceFactory sourceFactory;
- _AnalysisSessionImpl(
- this.analysisContext,
+ _MicroAnalysisSessionImpl(
this.declaredVariables,
this.sourceFactory,
) : super(null);
+
@override
ResourceProvider get resourceProvider =>
analysisContext.contextRoot.resourceProvider;
@override
+ UriConverter get uriConverter {
+ return _UriConverterImpl(
+ analysisContext.contextRoot.resourceProvider,
+ sourceFactory,
+ );
+ }
+
+ @override
FileResult getFile(String path) {
return FileResultImpl(
this,
@@ -95,16 +172,20 @@
}
@override
- Future<ResolvedUnitResult> getResolvedUnit(String path) async {
- return analysisContext.fileResolver.resolve(path);
+ Future<ResolvedLibraryResult> getResolvedLibrary(String path) async {
+ var resolvedUnit = await getResolvedUnit(path);
+ return ResolvedLibraryResultImpl(
+ this,
+ path,
+ resolvedUnit.uri,
+ resolvedUnit.libraryElement,
+ [resolvedUnit],
+ );
}
@override
- UriConverter get uriConverter {
- return _UriConverterImpl(
- analysisContext.contextRoot.resourceProvider,
- sourceFactory,
- );
+ Future<ResolvedUnitResult> getResolvedUnit(String path) async {
+ return analysisContext.fileResolver.resolve(path);
}
@override
diff --git a/pkg/analyzer/lib/src/dart/micro/library_graph.dart b/pkg/analyzer/lib/src/dart/micro/library_graph.dart
index 30f89ed..c392e42 100644
--- a/pkg/analyzer/lib/src/dart/micro/library_graph.dart
+++ b/pkg/analyzer/lib/src/dart/micro/library_graph.dart
@@ -226,6 +226,11 @@
directReferencedLibraries..addAll(importedFiles)..addAll(exportedFiles);
}
+ @override
+ String toString() {
+ return path;
+ }
+
FileState _fileForRelativeUri(String relativeUri) {
if (relativeUri.isEmpty) {
return _fsState.unresolvedFile;
@@ -415,7 +420,13 @@
removedFiles.add(file);
_uriToFile.remove(file.uri);
- for (var reference in file.referencingFiles) {
+ // The removed file does not reference other file anymore.
+ for (var referencedFile in file.directReferencedFiles) {
+ referencedFile.referencingFiles.remove(file);
+ }
+
+ // Recursively remove files that reference the removed file.
+ for (var reference in file.referencingFiles.toList()) {
changeFile(reference.path, removedFiles);
}
}
diff --git a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
index f6b5fc2..469b161 100644
--- a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
+++ b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
@@ -2,17 +2,15 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'dart:async';
import 'dart:typed_data';
-import 'package:analyzer/dart/analysis/declared_variables.dart';
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/analysis/results.dart';
-import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
-import 'package:analyzer/src/context/context.dart';
import 'package:analyzer/src/context/packages.dart';
import 'package:analyzer/src/dart/analysis/byte_store.dart';
import 'package:analyzer/src/dart/analysis/context_root.dart';
@@ -20,7 +18,6 @@
import 'package:analyzer/src/dart/analysis/feature_set_provider.dart';
import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:analyzer/src/dart/analysis/results.dart';
-import 'package:analyzer/src/dart/analysis/session.dart';
import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
import 'package:analyzer/src/dart/micro/analysis_context.dart';
import 'package:analyzer/src/dart/micro/library_analyzer.dart';
@@ -69,23 +66,15 @@
final Workspace workspace;
- /// If not `null`, the library context will be reset after the specified
- /// interval of inactivity. Keeping library context with loaded elements
- /// significantly improves performance of resolution, because we don't have
- /// to resynthesize elements, build export scopes for libraries, etc.
- /// However keeping elements that we don't need anymore, or when the user
- /// does not work with files, is wasteful.
- ///
- /// TODO(scheglov) use it
- final Duration libraryContextResetDuration;
+ _LibraryContextReset _libraryContextReset;
/// This field gets value only during testing.
FileResolverTestView testView;
- MicroAnalysisContextImpl analysisContext;
-
FileSystemState fsState;
+ MicroContextObjects contextObjects;
+
_LibraryContext libraryContext;
FileResolver(
@@ -96,8 +85,13 @@
this.getFileDigest,
this.prefetchFiles, {
@required Workspace workspace,
- this.libraryContextResetDuration,
- }) : this.workspace = workspace;
+ Duration libraryContextResetTimeout = const Duration(seconds: 60),
+ }) : this.workspace = workspace {
+ _libraryContextReset = _LibraryContextReset(
+ fileResolver: this,
+ resetTimeout: libraryContextResetTimeout,
+ );
+ }
FeatureSet get defaultFeatureSet => FeatureSet.fromEnableFlags([]);
@@ -123,153 +117,140 @@
}
}
+ void dispose() {
+ _libraryContextReset.dispose();
+ }
+
ErrorsResult getErrors(String path) {
_throwIfNotAbsoluteNormalizedPath(path);
- return logger.run('Get errors for $path', () {
- var fileContext = getFileContext(path, withLog: true);
- var file = fileContext.file;
+ return _withLibraryContextReset(() {
+ return logger.run('Get errors for $path', () {
+ var fileContext = getFileContext(path);
+ var file = fileContext.file;
- var errorsSignatureBuilder = ApiSignature();
- errorsSignatureBuilder.addBytes(file.libraryCycle.signature);
- errorsSignatureBuilder.addBytes(file.digest);
- var errorsSignature = errorsSignatureBuilder.toByteList();
+ var errorsSignatureBuilder = ApiSignature();
+ errorsSignatureBuilder.addBytes(file.libraryCycle.signature);
+ errorsSignatureBuilder.addBytes(file.digest);
+ var errorsSignature = errorsSignatureBuilder.toByteList();
- var errorsKey = file.path + '.errors';
- var bytes = byteStore.get(errorsKey);
+ var errorsKey = file.path + '.errors';
+ var bytes = byteStore.get(errorsKey);
- List<AnalysisError> errors;
- if (bytes != null) {
- var data = CiderUnitErrors.fromBuffer(bytes);
- if (const ListEquality().equals(data.signature, errorsSignature)) {
- errors = data.errors.map((error) {
- return ErrorEncoding.decode(file.source, error);
- }).toList();
+ List<AnalysisError> errors;
+ if (bytes != null) {
+ var data = CiderUnitErrors.fromBuffer(bytes);
+ if (const ListEquality().equals(data.signature, errorsSignature)) {
+ errors = data.errors.map((error) {
+ return ErrorEncoding.decode(file.source, error);
+ }).toList();
+ }
}
- }
- if (errors == null) {
- var unitResult = resolve(path);
- errors = unitResult.errors;
+ if (errors == null) {
+ var unitResult = resolve(path);
+ errors = unitResult.errors;
- bytes = CiderUnitErrorsBuilder(
- signature: errorsSignature,
- errors: errors.map((ErrorEncoding.encode)).toList(),
- ).toBuffer();
- byteStore.put(errorsKey, bytes);
- }
+ bytes = CiderUnitErrorsBuilder(
+ signature: errorsSignature,
+ errors: errors.map((ErrorEncoding.encode)).toList(),
+ ).toBuffer();
+ byteStore.put(errorsKey, bytes);
+ }
- return ErrorsResultImpl(
- libraryContext.analysisSession,
- path,
- file.uri,
- file.lineInfo,
- false, // isPart
- errors,
- );
+ return ErrorsResultImpl(
+ contextObjects.analysisSession,
+ path,
+ file.uri,
+ file.lineInfo,
+ false, // isPart
+ errors,
+ );
+ });
});
}
- FileContext getFileContext(String path, {bool withLog = false}) {
- FileContext perform() {
- var analysisOptions = _getAnalysisOptions(path);
+ FileContext getFileContext(String path) {
+ var analysisOptions = _getAnalysisOptions(path);
+ _createContext(path, analysisOptions);
- _createContext(analysisOptions);
-
- var file = fsState.getFileForPath(path);
- return FileContext(analysisOptions, file);
- }
-
- if (withLog) {
- return logger.run('Get file $path', () {
- try {
- return getFileContext(path);
- } finally {
- fsState.logStatistics();
- }
- });
- } else {
- return perform();
- }
+ var file = fsState.getFileForPath(path);
+ return FileContext(analysisOptions, file);
}
String getLibraryLinkedSignature(String path) {
_throwIfNotAbsoluteNormalizedPath(path);
- var fileContext = getFileContext(path);
- var file = fileContext.file;
+ var file = fsState.getFileForPath(path);
return file.libraryCycle.signatureStr;
}
ResolvedUnitResult resolve(String path) {
_throwIfNotAbsoluteNormalizedPath(path);
- return logger.run('Resolve $path', () {
- var fileContext = getFileContext(path, withLog: true);
- var file = fileContext.file;
+ return _withLibraryContextReset(() {
+ return logger.run('Resolve $path', () {
+ var fileContext = getFileContext(path);
+ var file = fileContext.file;
- libraryContext.load2(file);
+ libraryContext.load2(file);
- testView?.addResolvedFile(path);
+ testView?.addResolvedFile(path);
- var errorListener = RecordingErrorListener();
- var content = resourceProvider.getFile(path).readAsStringSync();
- var unit = file.parse(errorListener, content);
+ var errorListener = RecordingErrorListener();
+ var content = resourceProvider.getFile(path).readAsStringSync();
+ var unit = file.parse(errorListener, content);
- Map<FileState, UnitAnalysisResult> results;
- logger.run('Compute analysis results', () {
- var libraryAnalyzer = LibraryAnalyzer(
- fileContext.analysisOptions,
- analysisContext.declaredVariables,
- sourceFactory,
- (_) => true,
- // _isLibraryUri
- libraryContext.analysisContext,
- libraryContext.elementFactory,
- libraryContext.inheritanceManager,
- file,
- resourceProvider,
- (String path) => resourceProvider.getFile(path).readAsStringSync(),
+ Map<FileState, UnitAnalysisResult> results;
+ logger.run('Compute analysis results', () {
+ var libraryAnalyzer = LibraryAnalyzer(
+ fileContext.analysisOptions,
+ contextObjects.declaredVariables,
+ sourceFactory,
+ (_) => true, // _isLibraryUri
+ contextObjects.analysisContext,
+ libraryContext.elementFactory,
+ libraryContext.inheritanceManager,
+ file,
+ resourceProvider,
+ (String path) => resourceProvider.getFile(path).readAsStringSync(),
+ );
+
+ results = libraryAnalyzer.analyzeSync();
+ });
+ UnitAnalysisResult fileResult = results[file];
+
+ return ResolvedUnitResultImpl(
+ contextObjects.analysisSession,
+ path,
+ file.uri,
+ file.exists,
+ content,
+ unit.lineInfo,
+ false, // isPart
+ fileResult.unit,
+ fileResult.errors,
);
-
- results = libraryAnalyzer.analyzeSync();
});
- UnitAnalysisResult fileResult = results[file];
-
- return ResolvedUnitResultImpl(
- analysisContext.currentSession,
- path,
- file.uri,
- file.exists,
- content,
- unit.lineInfo,
- false, // isPart
- fileResult.unit,
- fileResult.errors,
- );
});
}
- /// Make sure that [analysisContext], [fsState] and [libraryContext] are
- /// compatible with the given [fileAnalysisOptions].
+ /// Make sure that [fsState], [contextObjects], and [libraryContext] are
+ /// created and configured with the given [fileAnalysisOptions].
///
- /// Specifically we check that `implicit-casts` and `strict-inference`
- /// flags are the same, so the type systems would be the same.
- void _createContext(AnalysisOptionsImpl fileAnalysisOptions) {
- if (analysisContext != null) {
- var analysisOptions = analysisContext.analysisOptions;
- var analysisOptionsImpl = analysisOptions as AnalysisOptionsImpl;
- if (analysisOptionsImpl.implicitCasts !=
- fileAnalysisOptions.implicitCasts ||
- analysisOptionsImpl.strictInference !=
- fileAnalysisOptions.strictInference) {
- logger.writeln(
- 'Reset the context, different type system affecting options.',
- );
- fsState = null; // TODO(scheglov) don't do this
- analysisContext = null;
- libraryContext = null;
- }
+ /// The [fsState] is not affected by [fileAnalysisOptions].
+ ///
+ /// The [fileAnalysisOptions] only affect reported diagnostics, but not
+ /// elements and types. So, we really need to reconfigure only when we are
+ /// going to resolve some files using these new options.
+ ///
+ /// Specifically, "implicit casts" and "strict inference" affect the type
+ /// system. And there are lints that are enabled for one package, but not
+ /// for another.
+ void _createContext(String path, AnalysisOptionsImpl fileAnalysisOptions) {
+ if (contextObjects != null) {
+ contextObjects.analysisOptions = fileAnalysisOptions;
+ return;
}
var analysisOptions = AnalysisOptionsImpl()
@@ -290,42 +271,33 @@
byteStore,
sourceFactory,
analysisOptions,
- Uint32List(0), // linkedSalt
+ Uint32List(0),
+ // linkedSalt
featureSetProvider,
getFileDigest,
prefetchFiles,
);
}
- if (analysisContext == null) {
+ if (contextObjects == null) {
var rootFolder = resourceProvider.getFolder(workspace.root);
- var root = ContextRootImpl(
- resourceProvider,
- rootFolder,
- );
-
+ var root = ContextRootImpl(resourceProvider, rootFolder);
root.included.add(rootFolder);
- analysisContext = MicroAnalysisContextImpl(
- this,
- root,
- analysisOptions,
- DeclaredVariables(),
- sourceFactory,
- resourceProvider,
+ contextObjects = createMicroContextObjects(
+ fileResolver: this,
+ analysisOptions: analysisOptions,
+ sourceFactory: sourceFactory,
+ root: root,
+ resourceProvider: resourceProvider,
workspace: workspace,
);
- }
- if (libraryContext == null) {
libraryContext = _LibraryContext(
logger,
resourceProvider,
byteStore,
- analysisContext.currentSession,
- analysisContext.analysisOptions,
- sourceFactory,
- analysisContext.declaredVariables,
+ contextObjects,
);
}
}
@@ -344,7 +316,7 @@
/// Return the analysis options.
///
- /// If the [optionsFile] is not `null`, read it.
+ /// If the [path] is not `null`, read it.
///
/// If the [workspace] is a [WorkspaceWithDefaultAnalysisOptions], get the
/// default options, if the file exists.
@@ -395,6 +367,19 @@
}
}
+ /// Run the [operation] that uses the library context, by locking it first,
+ /// so that it is not reset while the operating is still running, and
+ /// unlocking after the operation is done, so that the library context
+ /// will be reset after some timeout.
+ T _withLibraryContextReset<T>(T Function() operation) {
+ _libraryContextReset.lock();
+ try {
+ return operation();
+ } finally {
+ _libraryContextReset.unlock();
+ }
+ }
+
static File _getFile(Folder directory, String name) {
Resource resource = directory.getChild(name);
if (resource is File && resource.exists) {
@@ -419,9 +404,8 @@
final PerformanceLog logger;
final ResourceProvider resourceProvider;
final MemoryByteStore byteStore;
- final AnalysisSession analysisSession;
+ final MicroContextObjects contextObjects;
- AnalysisContextImpl analysisContext;
LinkedElementFactory elementFactory;
InheritanceManager3 inheritanceManager;
@@ -431,18 +415,9 @@
this.logger,
this.resourceProvider,
this.byteStore,
- this.analysisSession,
- AnalysisOptionsImpl analysisOptions,
- SourceFactory sourceFactory,
- DeclaredVariables declaredVariables,
+ this.contextObjects,
) {
- var synchronousSession =
- SynchronousSession(analysisOptions, declaredVariables);
- analysisContext = AnalysisContextImpl(
- synchronousSession,
- sourceFactory,
- );
-
+ // TODO(scheglov) remove it?
_createElementFactory();
}
@@ -541,7 +516,7 @@
// linker might have set the type provider. So, clear it, and recreate
// the element factory - it is empty anyway.
if (!elementFactory.hasDartCore) {
- analysisContext.clearTypeProvider();
+ contextObjects.analysisContext.clearTypeProvider();
_createElementFactory();
}
var cBundle = CiderLinkedLibraryCycle.fromBuffer(bytes);
@@ -585,14 +560,15 @@
void _createElementFactory() {
elementFactory = LinkedElementFactory(
- analysisContext,
- analysisSession,
+ contextObjects.analysisContext,
+ contextObjects.analysisSession,
Reference.root(),
);
}
/// Ensure that type provider is created.
void _createElementFactoryTypeProvider() {
+ var analysisContext = contextObjects.analysisContext;
if (analysisContext.typeProviderNonNullableByDefault == null) {
var dartCore = elementFactory.libraryOfUri('dart:core');
var dartAsync = elementFactory.libraryOfUri('dart:async');
@@ -608,3 +584,61 @@
);
}
}
+
+/// The helper to reset the library context will be reset after the specified
+/// interval of inactivity. Keeping library context with loaded elements
+/// significantly improves performance of resolution, because we don't have
+/// to resynthesize elements, build export scopes for libraries, etc.
+/// However keeping elements that we don't need anymore, or when the user
+/// does not work with files, is wasteful.
+class _LibraryContextReset {
+ final FileResolver fileResolver;
+ final Duration resetTimeout;
+
+ /// The lock level, incremented by [lock], and decremented by [unlock].
+ /// The timeout timer is started when the level reaches zero.
+ int _lockLevel = 0;
+ Timer _timer;
+
+ _LibraryContextReset({
+ @required this.fileResolver,
+ @required this.resetTimeout,
+ });
+
+ void dispose() {
+ _stop();
+ }
+
+ /// Stop the timeout timer, and increment the lock level. The library context
+ /// will be not reset until [unlock] will bring the lock level back to zero.
+ void lock() {
+ _stop();
+ _lockLevel++;
+ }
+
+ /// Unlock the timer, the library context will be reset after the timeout.
+ void unlock() {
+ assert(_lockLevel > 0);
+ _lockLevel--;
+
+ if (_lockLevel == 0) {
+ _stop();
+ if (resetTimeout != null) {
+ _timer = Timer(resetTimeout, () {
+ _timer = null;
+ if (fileResolver.libraryContext != null) {
+ fileResolver.contextObjects = null;
+ fileResolver.libraryContext = null;
+ }
+ });
+ }
+ }
+ }
+
+ void _stop() {
+ if (_timer != null) {
+ _timer.cancel();
+ _timer = null;
+ }
+ }
+}
diff --git a/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart b/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
index 19c607e..fad0ca3 100644
--- a/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
@@ -356,6 +356,13 @@
}
@override
+ bool isLocalVariableWithoutDeclaredType(PromotableElement variable) {
+ return variable is LocalVariableElement &&
+ variable.hasImplicitType &&
+ variable.initializer == null;
+ }
+
+ @override
bool isSameType(covariant TypeImpl type1, covariant TypeImpl type2) {
return type1 == type2;
}
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index 8212c01..b7ad7d7 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -1935,7 +1935,7 @@
//
// ```dart
// %uri="lib/optedOut.dart"
- // // @dart = 2.9
+ // // @dart = 2.8
// String s;
// ```
//
@@ -9632,7 +9632,7 @@
StaticWarningCode(
'REDIRECT_TO_INVALID_RETURN_TYPE',
"The return type '{0}' of the redirected constructor isn't "
- "assignable to '{1}'.",
+ "a subtype of '{1}'.",
correction: "Try redirecting to a different constructor.",
hasPublishedDocs: true);
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index a44252f..3d0f25e 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -39,6 +39,39 @@
import 'package:analyzer/src/generated/sdk.dart' show DartSdk, SdkLibrary;
import 'package:analyzer/src/task/strong/checker.dart';
+class EnclosingExecutableContext {
+ final ExecutableElement element;
+ final bool isAsynchronous;
+ final bool isConstConstructor;
+ final bool isFactoryConstructor;
+ final bool isGenerator;
+ final bool isStaticMethod;
+
+ /// The return statements that have a value.
+ final List<ReturnStatement> _returnsWith = [];
+
+ /// The return statements that do not have a value.
+ final List<ReturnStatement> _returnsWithout = [];
+
+ EnclosingExecutableContext(this.element)
+ : isAsynchronous = element != null && element.isAsynchronous,
+ isConstConstructor = element is ConstructorElement && element.isConst,
+ isFactoryConstructor =
+ element is ConstructorElement && element.isFactory,
+ isGenerator = element != null && element.isGenerator,
+ isStaticMethod = _isStaticMethod(element);
+
+ EnclosingExecutableContext.empty() : this(null);
+
+ static bool _isStaticMethod(ExecutableElement element) {
+ var enclosing = element?.enclosingElement;
+ if (enclosing is ClassElement) {
+ return element.isStatic;
+ }
+ return false;
+ }
+}
+
/**
* A visitor used to traverse an AST structure looking for additional errors and
* warnings not covered by the parser and resolver.
@@ -80,26 +113,6 @@
final InheritanceManager3 _inheritanceManager;
/**
- * A flag indicating whether the visitor is currently within a constructor
- * declaration that is 'const'.
- *
- * See [visitConstructorDeclaration].
- */
- bool _isEnclosingConstructorConst = false;
-
- /**
- * A flag indicating whether we are currently within a function body marked as
- * being asynchronous.
- */
- bool _inAsync = false;
-
- /**
- * A flag indicating whether we are currently within a function body marked a
- * being a generator.
- */
- bool _inGenerator = false;
-
- /**
* A flag indicating whether the visitor is currently within a catch clause.
*
* See [visitCatchClause].
@@ -111,12 +124,6 @@
*/
bool _isInComment = false;
- /**
- * A flag indicating whether the visitor is currently within an instance
- * creation expression.
- */
- bool _isInConstInstanceCreation = false;
-
/// The stack of flags, where `true` at the top (last) of the stack indicates
/// that the visitor is in the initializer of a lazy local variable. When the
/// top is `false`, we might be not in a local variable, or it is not `lazy`,
@@ -154,20 +161,6 @@
bool _isInFunctionTypedFormalParameter = false;
/**
- * A flag indicating whether the visitor is currently within a static method.
- * By "method" here getter, setter and operator declarations are also implied
- * since they are all represented with a [MethodDeclaration] in the AST
- * structure.
- */
- bool _isInStaticMethod = false;
-
- /**
- * A flag indicating whether the visitor is currently within a factory
- * constructor.
- */
- bool _isInFactory = false;
-
- /**
* A flag indicating whether the visitor is currently within code in the SDK.
*/
bool _isInSystemLibrary = false;
@@ -197,22 +190,11 @@
ExtensionElement _enclosingExtension;
/**
- * The method or function that we are currently visiting, or `null` if we are
- * not inside a method or function.
+ * The context of the method or function that we are currently visiting, or
+ * `null` if we are not inside a method or function.
*/
- ExecutableElement _enclosingFunction;
-
- /**
- * The return statements found in the method or function that we are currently
- * visiting that have a return value.
- */
- List<ReturnStatement> _returnsWith = <ReturnStatement>[];
-
- /**
- * The return statements found in the method or function that we are currently
- * visiting that do not have a return value.
- */
- List<ReturnStatement> _returnsWithout = <ReturnStatement>[];
+ EnclosingExecutableContext _enclosingExecutable =
+ EnclosingExecutableContext.empty();
/// A table mapping name of the library to the export directive which export
/// this library.
@@ -260,11 +242,9 @@
DuplicateDefinitionVerifier(_currentLibrary, errorReporter) {
this._isInSystemLibrary = _currentLibrary.source.isInSystemLibrary;
this._hasExtUri = _currentLibrary.hasExtUri;
- _isEnclosingConstructorConst = false;
_isInCatchClause = false;
_isInStaticVariableDeclaration = false;
_isInConstructorInitializer = false;
- _isInStaticMethod = false;
_intType = _typeProvider.intType;
_typeSystem = _currentLibrary.typeSystem;
_options = _currentLibrary.context.analysisOptions;
@@ -297,7 +277,7 @@
assert(classElement is ClassElementImpl);
assert(_enclosingClass == null);
assert(_enclosingEnum == null);
- assert(_enclosingFunction == null);
+ assert(_enclosingExecutable == null);
_enclosingClass = classElement;
}
@@ -346,7 +326,7 @@
@override
void visitAwaitExpression(AwaitExpression node) {
- if (!_inAsync) {
+ if (!_enclosingExecutable.isAsynchronous) {
_errorReporter.reportErrorForToken(
CompileTimeErrorCode.AWAIT_IN_WRONG_CONTEXT, node.awaitKeyword);
}
@@ -394,26 +374,6 @@
}
@override
- void visitBlockFunctionBody(BlockFunctionBody node) {
- bool wasInAsync = _inAsync;
- bool wasInGenerator = _inGenerator;
- List<ReturnStatement> previousReturnsWith = _returnsWith;
- List<ReturnStatement> previousReturnsWithout = _returnsWithout;
- try {
- _inAsync = node.isAsynchronous;
- _inGenerator = node.isGenerator;
- _returnsWith = <ReturnStatement>[];
- _returnsWithout = <ReturnStatement>[];
- super.visitBlockFunctionBody(node);
- } finally {
- _inAsync = wasInAsync;
- _inGenerator = wasInGenerator;
- _returnsWith = previousReturnsWith;
- _returnsWithout = previousReturnsWithout;
- }
- }
-
- @override
void visitBreakStatement(BreakStatement node) {
SimpleIdentifier labelNode = node.label;
if (labelNode != null) {
@@ -511,31 +471,23 @@
@override
void visitConstructorDeclaration(ConstructorDeclaration node) {
- ExecutableElement outerFunction = _enclosingFunction;
- try {
- ConstructorElement constructorElement = node.declaredElement;
- _enclosingFunction = constructorElement;
- _isEnclosingConstructorConst = node.constKeyword != null;
- _isInFactory = node.factoryKeyword != null;
+ ConstructorElement element = node.declaredElement;
+ _withEnclosingExecutable(element, () {
_checkForInvalidModifierOnBody(
node.body, CompileTimeErrorCode.INVALID_MODIFIER_ON_CONSTRUCTOR);
- _checkForConstConstructorWithNonFinalField(node, constructorElement);
+ _checkForConstConstructorWithNonFinalField(node, element);
_checkForConstConstructorWithNonConstSuper(node);
_constructorFieldsVerifier.verify(node);
_checkForRedirectingConstructorErrorCodes(node);
_checkForMultipleSuperInitializers(node);
- _checkForRecursiveConstructorRedirect(node, constructorElement);
- if (!_checkForRecursiveFactoryRedirect(node, constructorElement)) {
+ _checkForRecursiveConstructorRedirect(node, element);
+ if (!_checkForRecursiveFactoryRedirect(node, element)) {
_checkForAllRedirectConstructorErrorCodes(node);
}
_checkForUndefinedConstructorInInitializerImplicit(node);
_checkForReturnInGenerativeConstructor(node);
super.visitConstructorDeclaration(node);
- } finally {
- _isEnclosingConstructorConst = false;
- _isInFactory = false;
- _enclosingFunction = outerFunction;
- }
+ });
}
@override
@@ -601,28 +553,19 @@
@override
void visitExpressionFunctionBody(ExpressionFunctionBody node) {
- bool wasInAsync = _inAsync;
- bool wasInGenerator = _inGenerator;
- try {
- _inAsync = node.isAsynchronous;
- _inGenerator = node.isGenerator;
- FunctionType functionType = _enclosingFunction?.type;
- DartType expectedReturnType = functionType == null
- ? DynamicTypeImpl.instance
- : functionType.returnType;
- ExecutableElement function = _enclosingFunction;
- bool isSetterWithImplicitReturn = function.hasImplicitReturnType &&
- function is PropertyAccessorElement &&
- function.isSetter;
- if (!isSetterWithImplicitReturn) {
- _checkForReturnOfInvalidType(node.expression, expectedReturnType,
- isArrowFunction: true);
- }
- super.visitExpressionFunctionBody(node);
- } finally {
- _inAsync = wasInAsync;
- _inGenerator = wasInGenerator;
+ ExecutableElement function = _enclosingExecutable.element;
+ FunctionType functionType = function?.type;
+ DartType expectedReturnType = functionType == null
+ ? DynamicTypeImpl.instance
+ : functionType.returnType;
+ bool isSetterWithImplicitReturn = function.hasImplicitReturnType &&
+ function is PropertyAccessorElement &&
+ function.isSetter;
+ if (!isSetterWithImplicitReturn) {
+ _checkForReturnOfInvalidType(node.expression, expectedReturnType,
+ isArrowFunction: true);
}
+ super.visitExpressionFunctionBody(node);
}
@override
@@ -730,10 +673,9 @@
functionElement.enclosingElement is! CompilationUnitElement) {
_hiddenElements.declare(functionElement);
}
- ExecutableElement outerFunction = _enclosingFunction;
- try {
+
+ _withEnclosingExecutable(functionElement, () {
SimpleIdentifier identifier = node.name;
- _enclosingFunction = functionElement;
TypeAnnotation returnType = node.returnType;
if (node.isGetter) {
GetterSetterTypesVerifier(
@@ -755,27 +697,21 @@
_checkForIllegalReturnType(returnType);
_checkForImplicitDynamicReturn(node.name, node.declaredElement);
super.visitFunctionDeclaration(node);
- } finally {
- _enclosingFunction = outerFunction;
- }
+ });
}
@override
void visitFunctionExpression(FunctionExpression node) {
_isInLateLocalVariable.add(false);
- // If this function expression is wrapped in a function declaration, don't
- // change the enclosingFunction field.
+
if (node.parent is! FunctionDeclaration) {
- ExecutableElement outerFunction = _enclosingFunction;
- try {
- _enclosingFunction = node.declaredElement;
+ _withEnclosingExecutable(node.declaredElement, () {
super.visitFunctionExpression(node);
- } finally {
- _enclosingFunction = outerFunction;
- }
+ });
} else {
super.visitFunctionExpression(node);
}
+
_isInLateLocalVariable.removeLast();
}
@@ -880,32 +816,25 @@
@override
void visitInstanceCreationExpression(InstanceCreationExpression node) {
- bool wasInConstInstanceCreation = _isInConstInstanceCreation;
- _isInConstInstanceCreation = node.isConst;
- try {
- ConstructorName constructorName = node.constructorName;
- TypeName typeName = constructorName.type;
- DartType type = typeName.type;
- if (type is InterfaceType) {
- _checkForConstOrNewWithAbstractClass(node, typeName, type);
- _checkForConstOrNewWithEnum(node, typeName, type);
- _checkForConstOrNewWithMixin(node, typeName, type);
- _requiredParametersVerifier.visitInstanceCreationExpression(node);
- if (_isInConstInstanceCreation) {
- _checkForConstWithNonConst(node);
- _checkForConstWithUndefinedConstructor(
- node, constructorName, typeName);
- _checkForConstDeferredClass(node, constructorName, typeName);
- } else {
- _checkForNewWithUndefinedConstructor(node, constructorName, typeName);
- }
- _checkForListConstructor(node, type);
+ ConstructorName constructorName = node.constructorName;
+ TypeName typeName = constructorName.type;
+ DartType type = typeName.type;
+ if (type is InterfaceType) {
+ _checkForConstOrNewWithAbstractClass(node, typeName, type);
+ _checkForConstOrNewWithEnum(node, typeName, type);
+ _checkForConstOrNewWithMixin(node, typeName, type);
+ _requiredParametersVerifier.visitInstanceCreationExpression(node);
+ if (node.isConst) {
+ _checkForConstWithNonConst(node);
+ _checkForConstWithUndefinedConstructor(node, constructorName, typeName);
+ _checkForConstDeferredClass(node, constructorName, typeName);
+ } else {
+ _checkForNewWithUndefinedConstructor(node, constructorName, typeName);
}
- _checkForImplicitDynamicType(typeName);
- super.visitInstanceCreationExpression(node);
- } finally {
- _isInConstInstanceCreation = wasInConstInstanceCreation;
+ _checkForListConstructor(node, type);
}
+ _checkForImplicitDynamicType(typeName);
+ super.visitInstanceCreationExpression(node);
}
@override
@@ -937,10 +866,7 @@
@override
void visitMethodDeclaration(MethodDeclaration node) {
- ExecutableElement previousFunction = _enclosingFunction;
- try {
- _isInStaticMethod = node.isStatic;
- _enclosingFunction = node.declaredElement;
+ _withEnclosingExecutable(node.declaredElement, () {
TypeAnnotation returnType = node.returnType;
if (node.isStatic && node.isGetter) {
GetterSetterTypesVerifier(
@@ -965,10 +891,7 @@
_checkForMustCallSuper(node);
_checkForWrongTypeParameterVarianceInMethod(node);
super.visitMethodDeclaration(node);
- } finally {
- _enclosingFunction = previousFunction;
- _isInStaticMethod = false;
- }
+ });
}
@override
@@ -1107,9 +1030,9 @@
@override
void visitReturnStatement(ReturnStatement node) {
if (node.expression == null) {
- _returnsWithout.add(node);
+ _enclosingExecutable._returnsWithout.add(node);
} else {
- _returnsWith.add(node);
+ _enclosingExecutable._returnsWith.add(node);
}
_checkForAllReturnStatementErrorCodes(node);
super.visitReturnStatement(node);
@@ -1358,11 +1281,12 @@
*/
void _checkForAllEmptyReturnStatementErrorCodes(
ReturnStatement statement, DartType expectedReturnType) {
- if (_inGenerator) {
+ if (_enclosingExecutable.isGenerator) {
return;
}
- var returnType =
- _inAsync ? _typeSystem.flatten(expectedReturnType) : expectedReturnType;
+ var returnType = _enclosingExecutable.isAsynchronous
+ ? _typeSystem.flatten(expectedReturnType)
+ : expectedReturnType;
if (returnType.isDynamic ||
returnType.isDartCoreNull ||
returnType.isVoid) {
@@ -1497,7 +1421,7 @@
* the enclosing method or function.
*/
void _checkForAllReturnStatementErrorCodes(ReturnStatement statement) {
- FunctionType functionType = _enclosingFunction?.type;
+ FunctionType functionType = _enclosingExecutable.element.type;
DartType expectedReturnType = functionType == null
? DynamicTypeImpl.instance
: functionType.returnType;
@@ -1506,7 +1430,7 @@
// RETURN_IN_GENERATIVE_CONSTRUCTOR
bool isGenerativeConstructor(ExecutableElement element) =>
element is ConstructorElement && !element.isFactory;
- if (isGenerativeConstructor(_enclosingFunction)) {
+ if (isGenerativeConstructor(_enclosingExecutable.element)) {
if (returnExpression == null) {
return;
}
@@ -1519,12 +1443,12 @@
if (returnExpression == null) {
_checkForAllEmptyReturnStatementErrorCodes(statement, expectedReturnType);
return;
- } else if (_inGenerator) {
+ } else if (_enclosingExecutable.isGenerator) {
// RETURN_IN_GENERATOR
_errorReporter.reportErrorForNode(
CompileTimeErrorCode.RETURN_IN_GENERATOR,
statement,
- [_inAsync ? "async*" : "sync*"]);
+ [_enclosingExecutable.isAsynchronous ? "async*" : "sync*"]);
return;
}
@@ -2009,7 +1933,7 @@
*/
void _checkForConstConstructorWithNonConstSuper(
ConstructorDeclaration constructor) {
- if (!_isEnclosingConstructorConst) {
+ if (!_enclosingExecutable.isConstConstructor) {
return;
}
// OK, const factory, checked elsewhere
@@ -2079,7 +2003,7 @@
void _checkForConstConstructorWithNonFinalField(
ConstructorDeclaration constructor,
ConstructorElement constructorElement) {
- if (!_isEnclosingConstructorConst) {
+ if (!_enclosingExecutable.isConstConstructor) {
return;
}
// check if there is non-final field
@@ -2121,7 +2045,7 @@
* See [CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION].
*/
void _checkForConstEvalThrowsException(ThrowExpression expression) {
- if (_isEnclosingConstructorConst) {
+ if (_enclosingExecutable.isConstConstructor) {
_errorReporter.reportErrorForNode(
CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION, expression);
}
@@ -2648,7 +2572,7 @@
return;
}
// report problem
- if (_isEnclosingConstructorConst) {
+ if (_enclosingExecutable.isConstConstructor) {
// TODO(paulberry): this error should be based on the actual type of the
// constant, not the static type. See dartbug.com/21119.
_errorReporter.reportErrorForNode(
@@ -2810,8 +2734,8 @@
// assignable to everything.
return;
}
- if (_enclosingFunction.isAsynchronous) {
- if (_enclosingFunction.isGenerator) {
+ if (_enclosingExecutable.isAsynchronous) {
+ if (_enclosingExecutable.isGenerator) {
_checkForIllegalReturnTypeCode(
returnType,
_typeProvider.streamElement,
@@ -2824,7 +2748,7 @@
StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE,
);
}
- } else if (_enclosingFunction.isGenerator) {
+ } else if (_enclosingExecutable.isGenerator) {
_checkForIllegalReturnTypeCode(
returnType,
_typeProvider.iterableElement,
@@ -2936,8 +2860,8 @@
return;
}
if (!_isInConstructorInitializer &&
- !_isInStaticMethod &&
- !_isInFactory &&
+ !_enclosingExecutable.isStaticMethod &&
+ !_enclosingExecutable.isFactoryConstructor &&
!_isInInstanceNotLateVariableDeclaration &&
!_isInStaticVariableDeclaration) {
return;
@@ -2978,10 +2902,10 @@
}
}
- if (_isInStaticMethod) {
+ if (_enclosingExecutable.isStaticMethod) {
_errorReporter.reportErrorForNode(
CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC, identifier);
- } else if (_isInFactory) {
+ } else if (_enclosingExecutable.isFactoryConstructor) {
_errorReporter.reportErrorForNode(
CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_FACTORY, identifier);
} else {
@@ -4259,10 +4183,10 @@
void _checkForReturnOfInvalidType(
Expression returnExpression, DartType expectedType,
{bool isArrowFunction = false}) {
- if (_enclosingFunction == null) {
+ if (_enclosingExecutable == null) {
return;
}
- if (_inGenerator) {
+ if (_enclosingExecutable.isGenerator) {
// "return expression;" is disallowed in generators, but this is checked
// elsewhere. Bare "return" is always allowed in generators regardless
// of the return type. So no need to do any further checking.
@@ -4276,7 +4200,7 @@
var toType = expectedType;
var fromType = expressionType;
- if (_inAsync) {
+ if (_enclosingExecutable.isAsynchronous) {
toType = _typeSystem.flatten(toType);
fromType = _typeSystem.flatten(fromType);
if (!_isLegalReturnType(_typeProvider.futureElement)) {
@@ -4289,14 +4213,14 @@
}
void reportTypeError() {
- String displayName = _enclosingFunction.displayName;
+ String displayName = _enclosingExecutable.element.displayName;
if (displayName.isEmpty) {
_errorReporter.reportErrorForNode(
StaticTypeWarningCode.RETURN_OF_INVALID_TYPE_FROM_CLOSURE,
returnExpression,
[fromType, toType]);
- } else if (_enclosingFunction is MethodElement) {
+ } else if (_enclosingExecutable.element is MethodElement) {
_errorReporter.reportErrorForNode(
StaticTypeWarningCode.RETURN_OF_INVALID_TYPE_FROM_METHOD,
returnExpression,
@@ -4328,8 +4252,9 @@
}
}
if (!expectedType.isVoid && !fromType.isVoid) {
- var checkWithType =
- !_inAsync ? fromType : _typeProvider.futureType2(fromType);
+ var checkWithType = !_enclosingExecutable.isAsynchronous
+ ? fromType
+ : _typeProvider.futureType2(fromType);
if (_typeSystem.isAssignableTo2(checkWithType, expectedType)) {
return;
}
@@ -4532,7 +4457,7 @@
}
void _checkForTypeParameterReferencedByStatic(SimpleIdentifier identifier) {
- if (_isInStaticMethod || _isInStaticVariableDeclaration) {
+ if (_enclosingExecutable.isStaticMethod || _isInStaticVariableDeclaration) {
var element = identifier.staticElement;
if (element is TypeParameterElement &&
element.enclosingElement is ClassElement) {
@@ -5436,7 +5361,7 @@
/// Returns whether a value with the type of the the enclosing function's
/// declared return type is assignable to [expectedElement].
bool _isLegalReturnType(ClassElement expectedElement) {
- DartType returnType = _enclosingFunction.returnType;
+ DartType returnType = _enclosingExecutable.element.returnType;
//
// When checking an async/sync*/async* method, we know the exact type
// that will be returned (e.g. Future, Iterable, or Stream).
@@ -5532,6 +5457,19 @@
return null;
}
+ void _withEnclosingExecutable(
+ ExecutableElement element,
+ void Function() operation,
+ ) {
+ var current = _enclosingExecutable;
+ try {
+ _enclosingExecutable = EnclosingExecutableContext(element);
+ operation();
+ } finally {
+ _enclosingExecutable = current;
+ }
+ }
+
/**
* Return [FieldElement]s that are declared in the [ClassDeclaration] with
* the given [constructor], but are not initialized.
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index 2636d14..0a696c6 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -476,12 +476,12 @@
*
* This affects the behavior of [isAssignableTo].
*/
- final bool implicitCasts;
+ bool implicitCasts;
/// A flag indicating whether inference failures are allowed, off by default.
///
/// This option is experimental and subject to change.
- final bool strictInference;
+ bool strictInference;
@override
final TypeProvider typeProvider;
@@ -1482,6 +1482,14 @@
return null;
}
+ void updateOptions({
+ @required bool implicitCasts,
+ @required bool strictInference,
+ }) {
+ this.implicitCasts = implicitCasts;
+ this.strictInference = strictInference;
+ }
+
List<DartType> _defaultTypeArguments(
List<TypeParameterElement> typeParameters,
) {
diff --git a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
index 71eb4d2..126e28a 100644
--- a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
+++ b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
@@ -253,6 +253,8 @@
class ArgumentError extends Error {
ArgumentError([message]);
+
+ static T checkNotNull<T>(T argument, [String, name]) => argument;
}
abstract class bool extends Object {
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 364a1d3..a6c70c1 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
name: analyzer
-version: 0.39.7
+version: 0.39.8
description: This package provides a library that performs static analysis of Dart code.
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer
@@ -7,7 +7,7 @@
sdk: '>=2.6.0 <3.0.0'
dependencies:
- _fe_analyzer_shared: ^2.2.0
+ _fe_analyzer_shared: ^3.0.0
args: ^1.0.0
charcode: ^1.1.0
collection: ^1.10.1
diff --git a/pkg/analyzer/test/generated/compile_time_error_code.dart b/pkg/analyzer/test/generated/compile_time_error_code.dart
index 9b6b82f..558b322 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code.dart
@@ -1485,43 +1485,6 @@
]);
}
- test_isInConstInstanceCreation_restored() async {
- // If ErrorVerifier._isInConstInstanceCreation is not properly restored on
- // exit from visitInstanceCreationExpression, the error at (1) will be
- // treated as a warning rather than an error.
- await assertErrorsInCode(r'''
-class Foo<T extends num> {
- const Foo(x, y);
-}
-const x = const Foo<int>(const Foo<int>(0, 1),
- const <Foo<String>>[]); // (1)
-''', [
- error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 110, 6),
- ]);
- }
-
- test_isInInstanceVariableInitializer_restored() async {
- // If ErrorVerifier._isInInstanceVariableInitializer is not properly
- // restored on exit from visitVariableDeclaration, the error at (1)
- // won't be detected.
- await assertErrorsInCode(r'''
-class Foo {
- var bar;
- Map foo = {
- 'bar': () {
- var _bar;
- },
- 'bop': _foo // (1)
- };
- _foo() {
- }
-}
-''', [
- error(HintCode.UNUSED_LOCAL_VARIABLE, 65, 4),
- error(CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER, 89, 4),
- ]);
- }
-
test_length_of_erroneous_constant() async {
// Attempting to compute the length of constant that couldn't be evaluated
// (due to an error) should not crash the analyzer (see dartbug.com/23383)
diff --git a/pkg/analyzer/test/src/dart/micro/file_resolution.dart b/pkg/analyzer/test/src/dart/micro/file_resolution.dart
index 605677e..ef3df6c 100644
--- a/pkg/analyzer/test/src/dart/micro/file_resolution.dart
+++ b/pkg/analyzer/test/src/dart/micro/file_resolution.dart
@@ -52,6 +52,7 @@
(String path) => _getDigest(path),
null,
workspace: workspace,
+ libraryContextResetTimeout: null,
);
fileResolver.testView = FileResolverTestView();
}
diff --git a/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart b/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
index 6166778..24b695d 100644
--- a/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
+++ b/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
@@ -311,7 +311,7 @@
// Implicit casts are disabled in 'aaa'.
var aPath = '/workspace/dart/aaa/lib/a.dart';
- var aResult = await assertErrorsInFile(aPath, r'''
+ await assertErrorsInFile(aPath, r'''
num a = 0;
int b = a;
''', [
@@ -320,16 +320,17 @@
// Implicit casts are enabled in 'bbb'.
var bPath = '/workspace/dart/bbb/lib/a.dart';
- var bResult = await assertErrorsInFile(bPath, r'''
+ await assertErrorsInFile(bPath, r'''
num a = 0;
int b = a;
''', []);
- // Packages 'aaa' and 'bbb' have different options affecting type system.
- // So, we cannot share the same context.
- expect(
- aResult.libraryElement.context,
- isNot(same(bResult.libraryElement.context)),
- );
+ // Implicit casts are still disabled in 'aaa'.
+ await assertErrorsInFile(aPath, r'''
+num a = 0;
+int b = a;
+''', [
+ error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 19, 1),
+ ]);
}
}
diff --git a/pkg/analyzer/test/src/dart/resolution/metadata_test.dart b/pkg/analyzer/test/src/dart/resolution/metadata_test.dart
index cfc3b74..487f00f 100644
--- a/pkg/analyzer/test/src/dart/resolution/metadata_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/metadata_test.dart
@@ -294,7 +294,7 @@
test_optIn_fromOptOut_class_getter() async {
newFile('/test/lib/a.dart', content: r'''
class A {
- const foo = 42;
+ static const foo = 42;
}
''');
@@ -399,7 +399,7 @@
test_optIn_fromOptOut_prefix_class_getter() async {
newFile('/test/lib/a.dart', content: r'''
class A {
- const foo = 0;
+ static const foo = 0;
}
''');
diff --git a/pkg/analyzer/test/src/diagnostics/implicit_this_reference_in_initializer_test.dart b/pkg/analyzer/test/src/diagnostics/implicit_this_reference_in_initializer_test.dart
index 8d86a32..aa3745b 100644
--- a/pkg/analyzer/test/src/diagnostics/implicit_this_reference_in_initializer_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/implicit_this_reference_in_initializer_test.dart
@@ -74,6 +74,25 @@
]);
}
+ test_instanceVariableInitializer_nestedLocal() async {
+ // Test that (1) does not prevent reporting an error at (2).
+ await assertErrorsInCode(r'''
+class A {
+ Map foo = {
+ 'a': () {
+ var v = 0; // (1)
+ v;
+ },
+ 'b': _foo // (2)
+ };
+
+ void _foo() {}
+}
+''', [
+ error(CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER, 87, 4),
+ ]);
+ }
+
test_invocation() async {
await assertErrorsInCode(r'''
class A {
@@ -97,28 +116,6 @@
]);
}
- test_isInInstanceVariableInitializer_restored() async {
- // If ErrorVerifier._isInInstanceVariableInitializer is not properly
- // restored on exit from visitVariableDeclaration, the error at (1)
- // won't be detected.
- await assertErrorsInCode(r'''
-class Foo {
- var bar;
- Map foo = {
- 'bar': () {
- var _bar;
- },
- 'bop': _foo // (1)
- };
- _foo() {
- }
-}
-''', [
- error(HintCode.UNUSED_LOCAL_VARIABLE, 65, 4),
- error(CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER, 89, 4),
- ]);
- }
-
test_prefixedIdentifier() async {
await assertNoErrorsInCode(r'''
class A {
diff --git a/pkg/analyzer/tool/diagnostics/diagnostics.md b/pkg/analyzer/tool/diagnostics/diagnostics.md
index 4ac0e53..e4481c9 100644
--- a/pkg/analyzer/tool/diagnostics/diagnostics.md
+++ b/pkg/analyzer/tool/diagnostics/diagnostics.md
@@ -1781,7 +1781,7 @@
Given a library that is opted out of null safety:
{% prettify dart %}
-// @dart = 2.9
+// @dart = 2.8
String s;
{% endprettify %}
@@ -5407,7 +5407,7 @@
### redirect_to_invalid_return_type
-_The return type '{0}' of the redirected constructor isn't assignable to '{1}'._
+_The return type '{0}' of the redirected constructor isn't a subtype of '{1}'._
#### Description
diff --git a/pkg/compiler/lib/src/common_elements.dart b/pkg/compiler/lib/src/common_elements.dart
index 80b1a65..9bbfd02 100644
--- a/pkg/compiler/lib/src/common_elements.dart
+++ b/pkg/compiler/lib/src/common_elements.dart
@@ -353,6 +353,10 @@
ClassEntity get jsInvocationMirrorClass;
+ ClassEntity get requiredSentinelClass;
+
+ InterfaceType get requiredSentinelType;
+
MemberEntity get invocationTypeArgumentGetter;
/// Interface used to determine if an object has the JavaScript
@@ -1556,6 +1560,13 @@
ClassEntity get jsInvocationMirrorClass =>
_jsInvocationMirrorClass ??= _findHelperClass('JSInvocationMirror');
+ ClassEntity _requiredSentinelClass;
+ @override
+ ClassEntity get requiredSentinelClass =>
+ _requiredSentinelClass ??= _findHelperClass('_Required');
+ @override
+ InterfaceType get requiredSentinelType => _getRawType(requiredSentinelClass);
+
MemberEntity _invocationTypeArgumentGetter;
@override
MemberEntity get invocationTypeArgumentGetter =>
diff --git a/pkg/compiler/lib/src/diagnostics/messages.dart b/pkg/compiler/lib/src/diagnostics/messages.dart
index d757f43..09f7fab 100644
--- a/pkg/compiler/lib/src/diagnostics/messages.dart
+++ b/pkg/compiler/lib/src/diagnostics/messages.dart
@@ -663,7 +663,6 @@
final CompilerOptions _options;
bool get terse => _options?.terseDiagnostics ?? false;
bool get _printLegacyStars => _options?.printLegacyStars ?? false;
- bool get _useNullSafety => _options?.useNullSafety ?? true;
bool get _useLegacySubtyping => _options?.useLegacySubtyping ?? false;
String message;
@@ -716,7 +715,6 @@
if (value is DartType) {
value = value.toStructuredText(
printLegacyStars: _printLegacyStars,
- useNullSafety: _useNullSafety,
useLegacySubtyping: _useLegacySubtyping);
} else if (value is ConstantValue) {
value = value.toDartText();
diff --git a/pkg/compiler/lib/src/elements/entities.dart b/pkg/compiler/lib/src/elements/entities.dart
index bad2d7c..e863b5b 100644
--- a/pkg/compiler/lib/src/elements/entities.dart
+++ b/pkg/compiler/lib/src/elements/entities.dart
@@ -264,58 +264,76 @@
/// debugging data stream.
static const String tag = 'parameter-structure';
- /// The number of required (positional) parameters.
- final int requiredParameters;
+ /// The number of required positional parameters.
+ final int requiredPositionalParameters;
/// The number of positional parameters.
final int positionalParameters;
- /// The named parameters sorted alphabetically.
+ /// All named parameters sorted alphabetically.
final List<String> namedParameters;
+ /// The required named parameters.
+ final Set<String> requiredNamedParameters;
+
/// The number of type parameters.
final int typeParameters;
- const ParameterStructure(this.requiredParameters, this.positionalParameters,
- this.namedParameters, this.typeParameters);
+ const ParameterStructure(
+ this.requiredPositionalParameters,
+ this.positionalParameters,
+ this.namedParameters,
+ this.requiredNamedParameters,
+ this.typeParameters);
- const ParameterStructure.getter() : this(0, 0, const <String>[], 0);
+ const ParameterStructure.getter()
+ : this(0, 0, const <String>[], const <String>{}, 0);
- const ParameterStructure.setter() : this(1, 1, const <String>[], 0);
+ const ParameterStructure.setter()
+ : this(1, 1, const <String>[], const <String>{}, 0);
factory ParameterStructure.fromType(FunctionType type) {
return new ParameterStructure(
type.parameterTypes.length,
type.parameterTypes.length + type.optionalParameterTypes.length,
type.namedParameters,
+ type.requiredNamedParameters,
type.typeVariables.length);
}
/// Deserializes a [ParameterStructure] object from [source].
factory ParameterStructure.readFromDataSource(DataSource source) {
source.begin(tag);
- int requiredParameters = source.readInt();
+ int requiredPositionalParameters = source.readInt();
int positionalParameters = source.readInt();
List<String> namedParameters = source.readStrings();
+ Set<String> requiredNamedParameters =
+ source.readStrings(emptyAsNull: true)?.toSet() ?? const <String>{};
int typeParameters = source.readInt();
source.end(tag);
- return new ParameterStructure(requiredParameters, positionalParameters,
- namedParameters, typeParameters);
+ return new ParameterStructure(
+ requiredPositionalParameters,
+ positionalParameters,
+ namedParameters,
+ requiredNamedParameters,
+ typeParameters);
}
/// Serializes this [ParameterStructure] to [sink].
void writeToDataSink(DataSink sink) {
sink.begin(tag);
- sink.writeInt(requiredParameters);
+ sink.writeInt(requiredPositionalParameters);
sink.writeInt(positionalParameters);
sink.writeStrings(namedParameters);
+ sink.writeStrings(requiredNamedParameters);
sink.writeInt(typeParameters);
sink.end(tag);
}
/// The number of optional parameters (positional or named).
int get optionalParameters =>
- positionalParameters - requiredParameters + namedParameters.length;
+ (positionalParameters - requiredPositionalParameters) +
+ (namedParameters.length - requiredNamedParameters.length);
/// The total number of parameters (required or optional).
int get totalParameters => positionalParameters + namedParameters.length;
@@ -323,26 +341,29 @@
/// Returns the [CallStructure] corresponding to a call site passing all
/// parameters both required and optional.
CallStructure get callStructure {
- return new CallStructure(positionalParameters + namedParameters.length,
- namedParameters, typeParameters);
+ return new CallStructure(totalParameters, namedParameters, typeParameters);
}
@override
int get hashCode => Hashing.listHash(
namedParameters,
- Hashing.objectHash(
- positionalParameters,
+ Hashing.setHash(
+ requiredNamedParameters,
Hashing.objectHash(
- requiredParameters, Hashing.objectHash(typeParameters))));
+ positionalParameters,
+ Hashing.objectHash(requiredPositionalParameters,
+ Hashing.objectHash(typeParameters)))));
@override
bool operator ==(other) {
if (identical(this, other)) return true;
if (other is! ParameterStructure) return false;
- if (requiredParameters != other.requiredParameters ||
+ if (requiredPositionalParameters != other.requiredPositionalParameters ||
positionalParameters != other.positionalParameters ||
typeParameters != other.typeParameters ||
- namedParameters.length != other.namedParameters.length) {
+ namedParameters.length != other.namedParameters.length ||
+ requiredNamedParameters.length !=
+ other.requiredNamedParameters.length) {
return false;
}
for (int i = 0; i < namedParameters.length; i++) {
@@ -350,6 +371,9 @@
return false;
}
}
+ for (String name in requiredNamedParameters) {
+ if (!other.requiredNamedParameters.contains(name)) return false;
+ }
return true;
}
@@ -363,9 +387,10 @@
}
sb.write('(');
sb.write(positionalParameters);
- if (namedParameters.length > 0) {
+ for (var name in namedParameters) {
sb.write(',');
- sb.write(namedParameters.join(','));
+ if (requiredNamedParameters.contains(name)) sb.write('req ');
+ sb.write(name);
}
sb.write(')');
return sb.toString();
@@ -375,13 +400,13 @@
String toString() {
StringBuffer sb = new StringBuffer();
sb.write('ParameterStructure(');
- sb.write('requiredParameters=$requiredParameters,');
+ sb.write('requiredPositionalParameters=$requiredPositionalParameters,');
sb.write('positionalParameters=$positionalParameters,');
sb.write('namedParameters={${namedParameters.join(',')}},');
+ sb.write('requiredNamedParameters={${requiredNamedParameters.join(',')}},');
sb.write('typeParameters=$typeParameters)');
return sb.toString();
}
- int get size =>
- positionalParameters + typeParameters + namedParameters.length;
+ int get size => totalParameters + typeParameters;
}
diff --git a/pkg/compiler/lib/src/elements/types.dart b/pkg/compiler/lib/src/elements/types.dart
index 7b56319..96702e1 100644
--- a/pkg/compiler/lib/src/elements/types.dart
+++ b/pkg/compiler/lib/src/elements/types.dart
@@ -5,7 +5,7 @@
import '../common/names.dart';
import '../common_elements.dart';
import '../serialization/serialization.dart';
-import '../util/util.dart' show equalElements, identicalElements;
+import '../util/util.dart' show equalElements, equalSets, identicalElements;
import 'entities.dart';
/// Hierarchy to describe types in Dart.
@@ -92,15 +92,15 @@
DartType get withoutNullability => this;
/// Is `true` if this type is a top type but not a legacy top type.
- bool _isStrongTop(bool useNullSafety) => false;
+ bool _isStrongTop(bool useLegacySubtyping) => false;
/// Is `true` if this type is a top type.
- bool _isTop(bool useNullSafety) => _isStrongTop(useNullSafety);
+ bool _isTop(bool useLegacySubtyping) => _isStrongTop(useLegacySubtyping);
/// Is `true` if every type argument of this type is a top type.
// TODO(fishythefish): Should we instead check if each type argument is at its
// bound?
- bool _treatAsRaw(bool useNullSafety) => true;
+ bool _treatAsRaw(bool useLegacySubtyping) => true;
/// Whether this type contains a type variable.
bool get containsTypeVariables => false;
@@ -131,12 +131,8 @@
String toString() => toStructuredText();
String toStructuredText(
- {bool printLegacyStars = true,
- bool useNullSafety = true,
- bool useLegacySubtyping = false}) =>
- _DartTypeToStringVisitor(
- printLegacyStars, useNullSafety, useLegacySubtyping)
- .run(this);
+ {bool printLegacyStars = true, bool useLegacySubtyping = false}) =>
+ _DartTypeToStringVisitor(printLegacyStars, useLegacySubtyping).run(this);
}
/// Pairs of [FunctionTypeVariable]s that are currently assumed to be
@@ -237,10 +233,11 @@
DartType get withoutNullability => baseType;
@override
- bool _isTop(bool useNullSafety) => baseType.isObject;
+ bool _isTop(bool useLegacySubtyping) => baseType.isObject;
@override
- bool _treatAsRaw(bool useNullSafety) => baseType._treatAsRaw(useNullSafety);
+ bool _treatAsRaw(bool useLegacySubtyping) =>
+ baseType._treatAsRaw(useLegacySubtyping);
@override
bool get containsTypeVariables => baseType.containsTypeVariables;
@@ -298,10 +295,11 @@
DartType get withoutNullability => baseType;
@override
- bool _isStrongTop(bool isLegacy) => baseType.isObject;
+ bool _isStrongTop(bool useLegacySubtyping) => baseType.isObject;
@override
- bool _treatAsRaw(bool useNullSafety) => baseType._treatAsRaw(useNullSafety);
+ bool _treatAsRaw(bool useLegacySubtyping) =>
+ baseType._treatAsRaw(useLegacySubtyping);
@override
bool get containsTypeVariables => baseType.containsTypeVariables;
@@ -359,7 +357,7 @@
}
@override
- bool _isStrongTop(bool useNullSafety) => useNullSafety ? false : isObject;
+ bool _isTop(bool useLegacySubtyping) => useLegacySubtyping && isObject;
@override
bool get isObject =>
@@ -380,9 +378,9 @@
}
@override
- bool _treatAsRaw(bool useNullSafety) {
+ bool _treatAsRaw(bool useLegacySubtyping) {
for (DartType type in typeArguments) {
- if (!type._isTop(useNullSafety)) return false;
+ if (!type._isTop(useLegacySubtyping)) return false;
}
return true;
}
@@ -567,7 +565,7 @@
}
@override
- bool _isStrongTop(bool useNullSafety) => true;
+ bool _isStrongTop(bool useLegacySubtyping) => true;
@override
R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) =>
@@ -597,7 +595,7 @@
}
@override
- bool _isStrongTop(bool useNullSafety) => true;
+ bool _isStrongTop(bool useLegacySubtyping) => true;
@override
R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) =>
@@ -627,7 +625,7 @@
}
@override
- bool _isStrongTop(bool useNullSafety) => true;
+ bool _isStrongTop(bool useLegacySubtyping) => true;
@override
R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) =>
@@ -668,7 +666,7 @@
}
@override
- bool _isStrongTop(bool useNullSafety) => true;
+ bool _isStrongTop(bool useLegacySubtyping) => true;
@override
R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) =>
@@ -689,9 +687,12 @@
final List<DartType> parameterTypes;
final List<DartType> optionalParameterTypes;
- /// The names of the named parameters ordered lexicographically.
+ /// The names of all named parameters ordered lexicographically.
final List<String> namedParameters;
+ /// The names of the required named parameters.
+ final Set<String> requiredNamedParameters;
+
/// The types of the named parameters in the order corresponding to the
/// [namedParameters].
final List<DartType> namedParameterTypes;
@@ -703,6 +704,7 @@
this.parameterTypes,
this.optionalParameterTypes,
this.namedParameters,
+ this.requiredNamedParameters,
this.namedParameterTypes,
this.typeVariables) {
assert(returnType != null, "Invalid return type in $this.");
@@ -711,6 +713,8 @@
"Invalid optional parameter types in $this.");
assert(
!namedParameters.contains(null), "Invalid named parameters in $this.");
+ assert(!requiredNamedParameters.contains(null),
+ "Invalid required named parameters in $this.");
assert(!namedParameterTypes.contains(null),
"Invalid named parameter types in $this.");
assert(!typeVariables.contains(null), "Invalid type variables in $this.");
@@ -737,11 +741,19 @@
List<DartType> namedParameterTypes =
source._readDartTypes(functionTypeVariables);
List<String> namedParameters = List<String>(namedParameterTypes.length);
+ var requiredNamedParameters = <String>{};
for (int i = 0; i < namedParameters.length; i++) {
namedParameters[i] = source.readString();
+ if (source.readBool()) requiredNamedParameters.add(namedParameters[i]);
}
- return FunctionType._(returnType, parameterTypes, optionalParameterTypes,
- namedParameters, namedParameterTypes, typeVariables);
+ return FunctionType._(
+ returnType,
+ parameterTypes,
+ optionalParameterTypes,
+ namedParameters,
+ requiredNamedParameters,
+ namedParameterTypes,
+ typeVariables);
}
@override
@@ -760,6 +772,7 @@
sink._writeDartTypes(namedParameterTypes, functionTypeVariables);
for (String namedParameter in namedParameters) {
sink.writeString(namedParameter);
+ sink.writeBool(requiredNamedParameters.contains(namedParameter));
}
}
@@ -789,16 +802,19 @@
int get hashCode {
int hash = 3 * returnType.hashCode;
for (DartType parameter in parameterTypes) {
- hash = 17 * hash + 5 * parameter.hashCode;
+ hash = 19 * hash + 5 * parameter.hashCode;
}
for (DartType parameter in optionalParameterTypes) {
- hash = 19 * hash + 7 * parameter.hashCode;
+ hash = 23 * hash + 7 * parameter.hashCode;
}
for (String name in namedParameters) {
- hash = 23 * hash + 11 * name.hashCode;
+ hash = 29 * hash + 11 * name.hashCode;
}
for (DartType parameter in namedParameterTypes) {
- hash = 29 * hash + 13 * parameter.hashCode;
+ hash = 31 * hash + 13 * parameter.hashCode;
+ }
+ for (String name in requiredNamedParameters) {
+ hash = 37 * hash + 17 * name.hashCode;
}
return hash;
}
@@ -834,6 +850,7 @@
_equalTypes(optionalParameterTypes, other.optionalParameterTypes,
assumptions) &&
equalElements(namedParameters, other.namedParameters) &&
+ equalSets(requiredNamedParameters, other.requiredNamedParameters) &&
_equalTypes(
namedParameterTypes, other.namedParameterTypes, assumptions);
} finally {
@@ -1073,6 +1090,7 @@
parameterTypes,
optionalParameterTypes,
type.namedParameters,
+ type.requiredNamedParameters,
namedParameterTypes,
typeVariables));
}
@@ -1210,6 +1228,7 @@
newParameterTypes,
newOptionalParameterTypes,
type.namedParameters,
+ type.requiredNamedParameters,
newNamedParameterTypes,
newTypeVariables));
}
@@ -1507,7 +1526,6 @@
class _DartTypeToStringVisitor extends DartTypeVisitor<void, void> {
final bool _printLegacyStars;
- final bool _useNullSafety;
final bool _useLegacySubtyping;
final List _fragments = []; // Strings and _DeferredNames
bool _lastIsIdentifier = false;
@@ -1515,8 +1533,7 @@
Map<FunctionTypeVariable, _DeferredName> _variableToName;
Set<FunctionType> _genericFunctions;
- _DartTypeToStringVisitor(
- this._printLegacyStars, this._useNullSafety, this._useLegacySubtyping);
+ _DartTypeToStringVisitor(this._printLegacyStars, this._useLegacySubtyping);
String run(DartType type) {
_visit(type);
@@ -1668,8 +1685,7 @@
needsComma = _comma(needsComma);
_visit(typeVariable);
DartType bound = typeVariable.bound;
- if (!bound._isTop(_useNullSafety) &&
- (!_useLegacySubtyping || !bound.isObject)) {
+ if (!bound._isTop(_useLegacySubtyping)) {
_token(' extends ');
_visit(bound);
}
@@ -1749,7 +1765,7 @@
DartType legacyType(DartType baseType) {
DartType result;
- if (isTopType(baseType) ||
+ if (isStrongTopType(baseType) ||
baseType.isNull ||
baseType is LegacyType ||
baseType is NullableType) {
@@ -1820,6 +1836,7 @@
List<DartType> parameterTypes,
List<DartType> optionalParameterTypes,
List<String> namedParameters,
+ Set<String> requiredNamedParameters,
List<DartType> namedParameterTypes,
List<FunctionTypeVariable> typeVariables) {
FunctionType type = FunctionType._(
@@ -1827,6 +1844,7 @@
parameterTypes,
optionalParameterTypes,
namedParameters,
+ requiredNamedParameters,
namedParameterTypes,
typeVariables);
List<FunctionTypeVariable> normalizableVariables = typeVariables
@@ -1886,19 +1904,24 @@
t.optionalParameterTypes.map(_subst).toList();
List<DartType> namedParameterTypes =
t.namedParameterTypes.map(_subst).toList();
- return functionType(returnType, parameterTypes, optionalParameterTypes,
- t.namedParameters, namedParameterTypes, const []);
+ return functionType(
+ returnType,
+ parameterTypes,
+ optionalParameterTypes,
+ t.namedParameters,
+ t.requiredNamedParameters,
+ namedParameterTypes, const []);
}
/// Returns `true` if every type argument of [t] is a top type.
// TODO(fishythefish): Should we instead check if each type argument is at its
// bound?
- bool treatAsRawType(DartType t) => t._treatAsRaw(useNullSafety);
+ bool treatAsRawType(DartType t) => t._treatAsRaw(useLegacySubtyping);
/// Returns `true` if [t] is a top type, that is, a supertype of every type.
- bool isTopType(DartType t) => t._isTop(useNullSafety);
+ bool isTopType(DartType t) => t._isTop(useLegacySubtyping);
- bool isStrongTopType(DartType t) => t._isStrongTop(useNullSafety);
+ bool isStrongTopType(DartType t) => t._isStrongTop(useLegacySubtyping);
/// Returns `true` if [s] is a subtype of [t].
bool isSubtype(DartType s, DartType t) => _subtypeHelper(s, t);
@@ -2064,8 +2087,6 @@
if (!_isSubtype(s.returnType, t.returnType, env)) return false;
- // TODO(fishythefish): Support required named parameters.
-
List<DartType> sRequiredPositional = s.parameterTypes;
List<DartType> tRequiredPositional = t.parameterTypes;
int sRequiredPositionalLength = sRequiredPositional.length;
@@ -2108,25 +2129,38 @@
}
}
- List<String> sOptionalNamed = s.namedParameters;
- List<String> tOptionalNamed = t.namedParameters;
- List<DartType> sOptionalNamedTypes = s.namedParameterTypes;
- List<DartType> tOptionalNamedTypes = t.namedParameterTypes;
- int sOptionalNamedLength = sOptionalNamed.length;
- int tOptionalNamedLength = tOptionalNamed.length;
- for (int i = 0, j = 0; j < tOptionalNamedLength; j++) {
- String sName;
- String tName = tOptionalNamed[j];
- int comparison;
- do {
- if (i >= sOptionalNamedLength) return false;
- sName = sOptionalNamed[i++];
- comparison = sName.compareTo(tName);
- } while (comparison < 0);
- if (comparison > 0) return false;
- if (!_isSubtype(
- tOptionalNamedTypes[j], sOptionalNamedTypes[i - 1], env))
- return false;
+ List<String> sNamed = s.namedParameters;
+ List<String> tNamed = t.namedParameters;
+ Set<String> sRequiredNamed = s.requiredNamedParameters;
+ Set<String> tRequiredNamed = t.requiredNamedParameters;
+ List<DartType> sNamedTypes = s.namedParameterTypes;
+ List<DartType> tNamedTypes = t.namedParameterTypes;
+ int sNamedLength = sNamed.length;
+ int tNamedLength = tNamed.length;
+
+ int sIndex = 0;
+ for (int tIndex = 0; tIndex < tNamedLength; tIndex++) {
+ String tName = tNamed[tIndex];
+ while (true) {
+ if (sIndex >= sNamedLength) return false;
+ String sName = sNamed[sIndex++];
+ int comparison = sName.compareTo(tName);
+ if (comparison > 0) return false;
+ bool sIsRequired = sRequiredNamed.contains(sName);
+ if (comparison < 0) {
+ if (sIsRequired) return false;
+ continue;
+ }
+ bool tIsRequired = tRequiredNamed.contains(tName);
+ if (sIsRequired && !tIsRequired) return false;
+ if (!_isSubtype(
+ tNamedTypes[tIndex], sNamedTypes[sIndex - 1], env))
+ return false;
+ break;
+ }
+ }
+ while (sIndex < sNamedLength) {
+ if (sRequiredNamed.contains(sNamed[sIndex++])) return false;
}
return true;
} finally {
diff --git a/pkg/compiler/lib/src/inferrer/builder_kernel.dart b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
index 874bf6b..33d1bed 100644
--- a/pkg/compiler/lib/src/inferrer/builder_kernel.dart
+++ b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
@@ -229,7 +229,7 @@
ParameterStructure parameterStructure = function.parameterStructure;
return arguments.positional.length <
- parameterStructure.requiredParameters ||
+ parameterStructure.requiredPositionalParameters ||
arguments.positional.length > parameterStructure.positionalParameters ||
arguments.named.keys
.any((name) => !parameterStructure.namedParameters.contains(name));
diff --git a/pkg/compiler/lib/src/inferrer/inferrer_engine.dart b/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
index a510d20..0820252 100644
--- a/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
+++ b/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
@@ -772,7 +772,7 @@
int parameterIndex = 0;
types.strategy.forEachParameter(callee, (Local parameter) {
TypeInformation type;
- if (parameterIndex < parameterStructure.requiredParameters) {
+ if (parameterIndex < parameterStructure.requiredPositionalParameters) {
type = arguments.positional[parameterIndex];
} else if (parameterStructure.namedParameters.isNotEmpty) {
type = arguments.named[parameter.name];
diff --git a/pkg/compiler/lib/src/ir/visitors.dart b/pkg/compiler/lib/src/ir/visitors.dart
index cd46b51..5a65825 100644
--- a/pkg/compiler/lib/src/ir/visitors.dart
+++ b/pkg/compiler/lib/src/ir/visitors.dart
@@ -130,6 +130,12 @@
.skip(node.requiredParameterCount)
.toList()),
node.namedParameters.map((n) => n.name).toList(),
+ _options.useLegacySubtyping
+ ? const <String>{}
+ : node.namedParameters
+ .where((n) => n.isRequired)
+ .map((n) => n.name)
+ .toSet(),
node.namedParameters.map((n) => visitType(n.type)).toList(),
typeVariables ?? const <FunctionTypeVariable>[]);
DartType type = _convertNullability(functionType, node.nullability);
diff --git a/pkg/compiler/lib/src/js_backend/custom_elements_analysis.dart b/pkg/compiler/lib/src/js_backend/custom_elements_analysis.dart
index 2a547ec..3642a24 100644
--- a/pkg/compiler/lib/src/js_backend/custom_elements_analysis.dart
+++ b/pkg/compiler/lib/src/js_backend/custom_elements_analysis.dart
@@ -231,7 +231,7 @@
// function type.
_elementEnvironment.getFunctionType(constructor);
// Ignore constructors that cannot be called with zero arguments.
- if (constructor.parameterStructure.requiredParameters == 0) {
+ if (constructor.parameterStructure.requiredPositionalParameters == 0) {
result.add(constructor);
}
}
diff --git a/pkg/compiler/lib/src/js_backend/js_interop_analysis.dart b/pkg/compiler/lib/src/js_backend/js_interop_analysis.dart
index 8699611..5137d62 100644
--- a/pkg/compiler/lib/src/js_backend/js_interop_analysis.dart
+++ b/pkg/compiler/lib/src/js_backend/js_interop_analysis.dart
@@ -49,6 +49,7 @@
const <DartType>[],
new List<DartType>.filled(16, dartTypes.dynamicType()),
const <String>[],
+ const <String>{},
const <DartType>[],
const <FunctionTypeVariable>[]);
}
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types_new.dart b/pkg/compiler/lib/src/js_backend/runtime_types_new.dart
index 4c371aa..edbbc71 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types_new.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types_new.dart
@@ -359,7 +359,8 @@
_emitCode(Recipe.endOptionalGroup);
}
- void emitNamedGroup(List<String> names, List<DartType> types) {
+ void emitNamedGroup(
+ List<String> names, Set<String> requiredNames, List<DartType> types) {
assert(names.length == types.length);
first = true;
_emitCode(Recipe.startNamedGroup);
@@ -368,17 +369,18 @@
_emitCode(Recipe.separator);
}
_emitStringUnescaped(names[i]);
- _emitCode(Recipe.nameSeparator);
+ _emitCode(requiredNames.contains(names[i])
+ ? Recipe.requiredNameSeparator
+ : Recipe.nameSeparator);
visit(types[i], _);
first = false;
}
_emitCode(Recipe.endNamedGroup);
}
- // TODO(sra): These are optional named parameters. Handle required named
- // parameters the same way when they are implemented.
if (type.namedParameterTypes.isNotEmpty) {
- emitNamedGroup(type.namedParameters, type.namedParameterTypes);
+ emitNamedGroup(type.namedParameters, type.requiredNamedParameters,
+ type.namedParameterTypes);
}
_emitCode(Recipe.endFunctionArguments);
diff --git a/pkg/compiler/lib/src/js_backend/type_reference.dart b/pkg/compiler/lib/src/js_backend/type_reference.dart
index e6b39a4..de1a5f3 100644
--- a/pkg/compiler/lib/src/js_backend/type_reference.dart
+++ b/pkg/compiler/lib/src/js_backend/type_reference.dart
@@ -693,7 +693,7 @@
var parameterTypes = type.parameterTypes;
var optionalParameterTypes = type.optionalParameterTypes;
var namedParameters = type.namedParameters;
- // TODO(fishythefish): Handle required named parameters.
+ var requiredNamedParameters = type.requiredNamedParameters;
if (optionalParameterTypes.isEmpty &&
namedParameters.isEmpty &&
@@ -725,6 +725,9 @@
bool needsNamedComma = false;
for (int index = 0; index < namedParameters.length; index++) {
needsNamedComma = _comma(needsNamedComma);
+ if (requiredNamedParameters.contains(namedParameters[index])) {
+ _add(r'$req');
+ }
_identifier(namedParameters[index]);
_visit(type.namedParameterTypes[index], type);
}
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
index dc51d54..a400318 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
@@ -894,7 +894,7 @@
int index = 0;
_elementEnvironment.forEachParameter(method,
(DartType type, String name, ConstantValue defaultValue) {
- if (index >= parameterStructure.requiredParameters) {
+ if (index >= parameterStructure.requiredPositionalParameters) {
optionalParameterDefaultValues.add(defaultValue);
}
index++;
@@ -961,7 +961,8 @@
FunctionEntity method = element;
ParameterStructure parameterStructure = method.parameterStructure;
- int requiredParameterCount = parameterStructure.requiredParameters;
+ int requiredParameterCount =
+ parameterStructure.requiredPositionalParameters;
var /* List | Map */ optionalParameterDefaultValues;
int applyIndex = 0;
if (canBeApplied) {
@@ -1249,7 +1250,8 @@
FunctionEntity method = element;
ParameterStructure parameterStructure = method.parameterStructure;
- int requiredParameterCount = parameterStructure.requiredParameters;
+ int requiredParameterCount =
+ parameterStructure.requiredPositionalParameters;
var /* List | Map */ optionalParameterDefaultValues;
int applyIndex = 0;
if (canBeApplied) {
diff --git a/pkg/compiler/lib/src/js_model/element_map.dart b/pkg/compiler/lib/src/js_model/element_map.dart
index 00cb033..10bb603 100644
--- a/pkg/compiler/lib/src/js_model/element_map.dart
+++ b/pkg/compiler/lib/src/js_model/element_map.dart
@@ -106,6 +106,13 @@
ir.Member memberContext, ir.Expression expression,
{bool requireConstant: true, bool implicitNull: false});
+ /// Returns the [ConstantValue] for the sentinel used to indicate that a
+ /// parameter is required.
+ ///
+ /// These should only appear within the defaultValues object attached to
+ /// closures and tearoffs when emitting Function.apply.
+ ConstantValue getRequiredSentinelConstantValue();
+
/// Return the [ImportEntity] corresponding to [node].
ImportEntity getImport(ir.LibraryDependency node);
@@ -529,7 +536,7 @@
position++) {
ir.VariableDeclaration variable = node.positionalParameters[position];
f(variable,
- isOptional: position >= parameterStructure.requiredParameters,
+ isOptional: position >= parameterStructure.requiredPositionalParameters,
isElided: position >= parameterStructure.positionalParameters);
}
diff --git a/pkg/compiler/lib/src/js_model/element_map_impl.dart b/pkg/compiler/lib/src/js_model/element_map_impl.dart
index 78e93d5..9ebf74a 100644
--- a/pkg/compiler/lib/src/js_model/element_map_impl.dart
+++ b/pkg/compiler/lib/src/js_model/element_map_impl.dart
@@ -887,13 +887,17 @@
parameterTypes.add(getParameterType(variable));
}
}
- List<String> namedParameters = <String>[];
+ var namedParameters = <String>[];
+ var requiredNamedParameters = <String>{};
List<DartType> namedParameterTypes = <DartType>[];
List<ir.VariableDeclaration> sortedNamedParameters =
node.namedParameters.toList()..sort((a, b) => a.name.compareTo(b.name));
for (ir.VariableDeclaration variable in sortedNamedParameters) {
namedParameters.add(variable.name);
namedParameterTypes.add(getParameterType(variable));
+ if (variable.isRequired && !options.useLegacySubtyping) {
+ requiredNamedParameters.add(variable.name);
+ }
}
List<FunctionTypeVariable> typeVariables;
if (node.typeParameters.isNotEmpty) {
@@ -927,6 +931,7 @@
parameterTypes,
optionalParameterTypes,
namedParameters,
+ requiredNamedParameters,
namedParameterTypes,
typeVariables);
}
@@ -1487,6 +1492,12 @@
}
@override
+ ConstantValue getRequiredSentinelConstantValue() {
+ return new ConstructedConstantValue(
+ _commonElements.requiredSentinelType, <FieldEntity, ConstantValue>{});
+ }
+
+ @override
FunctionEntity getSuperNoSuchMethod(ClassEntity cls) {
while (cls != null) {
cls = elementEnvironment.getSuperClass(cls);
@@ -1779,13 +1790,24 @@
ParameterStructure _getParameterStructureFromFunctionNode(
ir.FunctionNode node) {
- int requiredParameters = node.requiredParameterCount;
+ int requiredPositionalParameters = node.requiredParameterCount;
int positionalParameters = node.positionalParameters.length;
int typeParameters = node.typeParameters.length;
- List<String> namedParameters =
- node.namedParameters.map((p) => p.name).toList()..sort();
- return new ParameterStructure(requiredParameters, positionalParameters,
- namedParameters, typeParameters);
+ var namedParameters = <String>[];
+ var requiredNamedParameters = <String>{};
+ for (var p in node.namedParameters.toList()
+ ..sort((a, b) => a.name.compareTo(b.name))) {
+ namedParameters.add(p.name);
+ if (p.isRequired && !options.useLegacySubtyping) {
+ requiredNamedParameters.add(p.name);
+ }
+ }
+ return new ParameterStructure(
+ requiredPositionalParameters,
+ positionalParameters,
+ namedParameters,
+ requiredNamedParameters,
+ typeParameters);
}
KernelClosureClassInfo constructClosureClass(
diff --git a/pkg/compiler/lib/src/js_model/elements.dart b/pkg/compiler/lib/src/js_model/elements.dart
index 89b4467..4929d21 100644
--- a/pkg/compiler/lib/src/js_model/elements.dart
+++ b/pkg/compiler/lib/src/js_model/elements.dart
@@ -729,9 +729,15 @@
static const String tag = 'signature-method';
JSignatureMethod(ClassEntity enclosingClass)
- : super(enclosingClass.library, enclosingClass, Names.signature,
- const ParameterStructure(0, 0, const [], 0), AsyncMarker.SYNC,
- isStatic: false, isExternal: false, isAbstract: false);
+ : super(
+ enclosingClass.library,
+ enclosingClass,
+ Names.signature,
+ const ParameterStructure(0, 0, const [], const {}, 0),
+ AsyncMarker.SYNC,
+ isStatic: false,
+ isExternal: false,
+ isAbstract: false);
factory JSignatureMethod.readFromDataSource(DataSource source) {
source.begin(tag);
diff --git a/pkg/compiler/lib/src/js_model/env.dart b/pkg/compiler/lib/src/js_model/env.dart
index 4187979..58716eb 100644
--- a/pkg/compiler/lib/src/js_model/env.dart
+++ b/pkg/compiler/lib/src/js_model/env.dart
@@ -647,7 +647,9 @@
DartType type = elementMap.getDartType(parameter.type);
String name = parameter.name;
ConstantValue defaultValue;
- if (isOptional) {
+ if (parameter.isRequired) {
+ defaultValue = elementMap.getRequiredSentinelConstantValue();
+ } else if (isOptional) {
if (parameter.initializer != null) {
defaultValue =
elementMap.getConstantValue(memberContext, parameter.initializer);
diff --git a/pkg/compiler/lib/src/js_model/js_world_builder.dart b/pkg/compiler/lib/src/js_model/js_world_builder.dart
index f9dfd30..f5d5955 100644
--- a/pkg/compiler/lib/src/js_model/js_world_builder.dart
+++ b/pkg/compiler/lib/src/js_model/js_world_builder.dart
@@ -818,6 +818,7 @@
parameterTypes,
optionalParameterTypes,
type.namedParameters,
+ type.requiredNamedParameters,
namedParameterTypes,
typeVariables);
}
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart
index b0c227b..3d53600 100644
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -511,12 +511,16 @@
}
}
List<String> namedParameters = <String>[];
+ Set<String> requiredNamedParameters = <String>{};
List<DartType> namedParameterTypes = <DartType>[];
List<ir.VariableDeclaration> sortedNamedParameters =
node.namedParameters.toList()..sort((a, b) => a.name.compareTo(b.name));
for (ir.VariableDeclaration variable in sortedNamedParameters) {
namedParameters.add(variable.name);
namedParameterTypes.add(getParameterType(variable));
+ if (variable.isRequired && !options.useLegacySubtyping) {
+ requiredNamedParameters.add(variable.name);
+ }
}
List<FunctionTypeVariable> typeVariables;
if (node.typeParameters.isNotEmpty) {
@@ -550,6 +554,7 @@
parameterTypes,
optionalParameterTypes,
namedParameters,
+ requiredNamedParameters,
namedParameterTypes,
typeVariables);
}
@@ -813,13 +818,25 @@
// constructors like calling a generic method.
{bool includeTypeParameters: true}) {
// TODO(johnniwinther): Cache the computed function type.
- int requiredParameters = node.requiredParameterCount;
+ int requiredPositionalParameters = node.requiredParameterCount;
int positionalParameters = node.positionalParameters.length;
int typeParameters = node.typeParameters.length;
- List<String> namedParameters =
- node.namedParameters.map((p) => p.name).toList()..sort();
- return new ParameterStructure(requiredParameters, positionalParameters,
- namedParameters, includeTypeParameters ? typeParameters : 0);
+ List<String> namedParameters = <String>[];
+ Set<String> requiredNamedParameters = <String>{};
+ List<ir.VariableDeclaration> sortedNamedParameters =
+ node.namedParameters.toList()..sort((a, b) => a.name.compareTo(b.name));
+ for (var variable in sortedNamedParameters) {
+ namedParameters.add(variable.name);
+ if (variable.isRequired && !options.useLegacySubtyping) {
+ requiredNamedParameters.add(variable.name);
+ }
+ }
+ return new ParameterStructure(
+ requiredPositionalParameters,
+ positionalParameters,
+ namedParameters,
+ requiredNamedParameters,
+ includeTypeParameters ? typeParameters : 0);
}
@override
diff --git a/pkg/compiler/lib/src/serialization/abstract_source.dart b/pkg/compiler/lib/src/serialization/abstract_source.dart
index 27435a1..fb968a5 100644
--- a/pkg/compiler/lib/src/serialization/abstract_source.dart
+++ b/pkg/compiler/lib/src/serialization/abstract_source.dart
@@ -232,8 +232,10 @@
new List<ir.NamedType>(namedParameterCount);
for (int index = 0; index < namedParameterCount; index++) {
String name = readString();
+ bool isRequired = readBool();
ir.DartType type = _readDartTypeNode(functionTypeVariables);
- namedParameters[index] = new ir.NamedType(name, type);
+ namedParameters[index] =
+ new ir.NamedType(name, type, isRequired: isRequired);
}
ir.TypedefType typedefType = _readDartTypeNode(functionTypeVariables);
end(functionTypeNodeTag);
diff --git a/pkg/compiler/lib/src/serialization/helpers.dart b/pkg/compiler/lib/src/serialization/helpers.dart
index 61023e8..5232b87 100644
--- a/pkg/compiler/lib/src/serialization/helpers.dart
+++ b/pkg/compiler/lib/src/serialization/helpers.dart
@@ -215,6 +215,7 @@
_sink.writeInt(node.namedParameters.length);
for (ir.NamedType parameter in node.namedParameters) {
_sink.writeString(parameter.name);
+ _sink.writeBool(parameter.isRequired);
_sink._writeDartTypeNode(parameter.type, functionTypeVariables);
}
_sink._writeDartTypeNode(node.typedefType, functionTypeVariables,
diff --git a/pkg/compiler/lib/src/ssa/type_builder.dart b/pkg/compiler/lib/src/ssa/type_builder.dart
index de1d2a5..36218f3 100644
--- a/pkg/compiler/lib/src/ssa/type_builder.dart
+++ b/pkg/compiler/lib/src/ssa/type_builder.dart
@@ -53,10 +53,15 @@
if (type == null) return null;
type = builder.localsHandler.substInContext(type);
if (_closedWorld.dartTypes.isTopType(type)) return null;
+ bool includeNull =
+ _closedWorld.dartTypes.useLegacySubtyping || type is NullableType;
+ type = type.withoutNullability;
if (type is! InterfaceType) return null;
// The type element is either a class or the void element.
ClassEntity element = (type as InterfaceType).element;
- return _abstractValueDomain.createNullableSubtype(element);
+ return includeNull
+ ? _abstractValueDomain.createNullableSubtype(element)
+ : _abstractValueDomain.createNonNullSubtype(element);
}
/// Create an instruction to simply trust the provided type.
diff --git a/pkg/compiler/lib/src/universe/call_structure.dart b/pkg/compiler/lib/src/universe/call_structure.dart
index 5410034..45603b8 100644
--- a/pkg/compiler/lib/src/universe/call_structure.dart
+++ b/pkg/compiler/lib/src/universe/call_structure.dart
@@ -147,9 +147,9 @@
}
bool signatureApplies(ParameterStructure parameters) {
- int requiredParameterCount = parameters.requiredParameters;
+ int requiredParameterCount = parameters.requiredPositionalParameters;
int optionalParameterCount = parameters.optionalParameters;
- int parameterCount = requiredParameterCount + optionalParameterCount;
+ int parameterCount = parameters.totalParameters;
if (argumentCount > parameterCount) return false;
if (positionalArgumentCount < requiredParameterCount) return false;
if (typeArgumentCount != 0) {
@@ -166,15 +166,22 @@
} else {
if (positionalArgumentCount > requiredParameterCount) return false;
assert(positionalArgumentCount == requiredParameterCount);
- if (namedArgumentCount > optionalParameterCount) return false;
+ if (namedArgumentCount >
+ optionalParameterCount + parameters.requiredNamedParameters.length)
+ return false;
int nameIndex = 0;
List<String> namedParameters = parameters.namedParameters;
+ int seenRequiredNamedParameters = 0;
+
for (String name in getOrderedNamedArguments()) {
bool found = false;
// Note: we start at the existing index because arguments are sorted.
while (nameIndex < namedParameters.length) {
- if (name == namedParameters[nameIndex]) {
+ String parameterName = namedParameters[nameIndex];
+ if (name == parameterName) {
+ if (parameters.requiredNamedParameters.contains(name))
+ seenRequiredNamedParameters++;
found = true;
break;
}
@@ -182,7 +189,8 @@
}
if (!found) return false;
}
- return true;
+ return seenRequiredNamedParameters ==
+ parameters.requiredNamedParameters.length;
}
}
diff --git a/pkg/compiler/lib/src/universe/member_usage.dart b/pkg/compiler/lib/src/universe/member_usage.dart
index 5fae2da..de26a23 100644
--- a/pkg/compiler/lib/src/universe/member_usage.dart
+++ b/pkg/compiler/lib/src/universe/member_usage.dart
@@ -707,7 +707,7 @@
_hasInvoke = false;
_areAllTypeParametersProvided = _parameterStructure.typeParameters == 0;
_providedPositionalParameters = _parameterStructure.positionalParameters ==
- _parameterStructure.requiredParameters
+ _parameterStructure.requiredPositionalParameters
? null
: 0;
if (!_parameterStructure.namedParameters.isEmpty) {
@@ -777,7 +777,7 @@
if (!_hasInvoke) return null;
if (isFullyUsed) return _parameterStructure;
return new ParameterStructure(
- _parameterStructure.requiredParameters,
+ _parameterStructure.requiredPositionalParameters,
_providedPositionalParameters ??
_parameterStructure.positionalParameters,
_unprovidedNamedParameters == null
@@ -785,6 +785,7 @@
: _parameterStructure.namedParameters
.where((n) => !_unprovidedNamedParameters.contains(n))
.toList(),
+ _parameterStructure.requiredNamedParameters,
_areAllTypeParametersProvided ? _parameterStructure.typeParameters : 0);
}
diff --git a/pkg/dartfix/CHANGELOG.md b/pkg/dartfix/CHANGELOG.md
index de84535..0b0c65d 100644
--- a/pkg/dartfix/CHANGELOG.md
+++ b/pkg/dartfix/CHANGELOG.md
@@ -1,3 +1,6 @@
+# 0.1.7
+* Improve experimental non-nullable migration support.
+
# 0.1.6
* Improve experimental non-nullable migration support.
diff --git a/pkg/dartfix/pubspec.yaml b/pkg/dartfix/pubspec.yaml
index 628c71b..c8de0ad 100644
--- a/pkg/dartfix/pubspec.yaml
+++ b/pkg/dartfix/pubspec.yaml
@@ -1,11 +1,11 @@
name: dartfix
-version: 0.1.6
+version: 0.1.7
description:
A tool for migrating Dart source to newer versions of the Dart SDK
and fixing common issues.
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/dartfix
environment:
- sdk: '>=2.3.0 <3.0.0'
+ sdk: '>=2.8.0 <3.0.0'
# Add the bin/dartfix.dart script to the scripts pub installs.
executables:
@@ -17,10 +17,10 @@
analysis_server_client: 1.1.3
args: ^1.4.0
cli_util: ^0.1.3
- path: ^1.6.0
- pub_semver: ^1.4.2
+ path: ^1.7.0
+ pub_semver: ^1.4.4
dev_dependencies:
- analyzer: ^0.37.0
+ analyzer: ^0.39.0
pedantic: ^1.8.0
- test: ^1.3.0
+ test: ^1.14.2
diff --git a/pkg/dev_compiler/test/modular_suite_nnbd.dart b/pkg/dev_compiler/test/modular_suite_nnbd.dart
index 41377bc..9c52552 100644
--- a/pkg/dev_compiler/test/modular_suite_nnbd.dart
+++ b/pkg/dev_compiler/test/modular_suite_nnbd.dart
@@ -244,7 +244,7 @@
var runjs = '''
import { dart, _isolate_helper } from 'dart_sdk.js';
import { main } from 'main.js';
- dart.strictSubtypeChecks(false);
+ dart.nullSafety(false);
_isolate_helper.startRootIsolate(() => {}, []);
main.main();
''';
diff --git a/pkg/dev_compiler/tool/ddb b/pkg/dev_compiler/tool/ddb
index 9abb66c..8585dac 100755
--- a/pkg/dev_compiler/tool/ddb
+++ b/pkg/dev_compiler/tool/ddb
@@ -269,7 +269,7 @@
function(sdk, app) {
'use strict';
if ($nnbd) {
- sdk.dart.strictSubtypeChecks($isNnbdStrong);
+ sdk.dart.nullSafety($isNnbdStrong);
}
sdk._debugger.registerDevtoolsFormatter();
app.$libname.main();
@@ -301,7 +301,7 @@
let main = require(\"./$basename\").$libname.main;
try {
if ($nnbd) {
- sdk.dart.strictSubtypeChecks($isNnbdStrong);
+ sdk.dart.nullSafety($isNnbdStrong);
}
sdk._isolate_helper.startRootIsolate(main, []);
} catch(e) {
@@ -334,7 +334,7 @@
let main = $libname.main;
try {
if ($nnbd) {
- dart.strictSubtypeChecks($isNnbdStrong);
+ dart.nullSafety($isNnbdStrong);
}
_isolate_helper.startRootIsolate(() => {}, []);
main();
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index b01af737..f9dfb2b 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -1555,12 +1555,22 @@
this, beginToken, name, typeArguments, arguments,
isTypeArgumentsInForest: isInForest));
}
+ } else if (receiver is ParserRecovery) {
+ push(new ParserErrorGenerator(this, null, fasta.messageSyntheticToken));
} else if (arguments == null) {
push(receiver);
} else {
push(finishSend(receiver, typeArguments, arguments, beginToken.charOffset,
isTypeArgumentsInForest: isInForest));
}
+ assert(checkState(beginToken, [
+ unionOfKinds([
+ ValueKinds.Expression,
+ ValueKinds.Generator,
+ ValueKinds.Initializer,
+ ValueKinds.ProblemBuilder
+ ])
+ ]));
}
@override
@@ -1570,8 +1580,6 @@
if (receiver is Generator) {
return receiver.doInvocation(charOffset, typeArguments, arguments,
isTypeArgumentsInForest: isTypeArgumentsInForest);
- } else if (receiver is ParserRecovery) {
- return new ParserErrorGenerator(this, null, fasta.messageSyntheticToken);
} else {
return forest.createExpressionInvocation(
charOffset, toValue(receiver), arguments);
@@ -3086,20 +3094,18 @@
@override
void handleNonNullAssertExpression(Token bang) {
assert(checkState(bang, [
- unionOfKinds([ValueKinds.Expression, ValueKinds.Generator])
+ unionOfKinds([
+ ValueKinds.Expression,
+ ValueKinds.Generator,
+ ValueKinds.Initializer,
+ ValueKinds.ProblemBuilder
+ ])
]));
if (!libraryBuilder.isNonNullableByDefault) {
reportNonNullAssertExpressionNotEnabled(bang);
}
- Object operand = pop();
- Expression expression;
- if (operand is Generator) {
- expression = operand.buildSimpleRead();
- } else {
- assert(operand is Expression);
- expression = operand;
- }
- push(forest.createNullCheck(offsetForToken(bang), expression));
+ Expression operand = popForValue();
+ push(forest.createNullCheck(offsetForToken(bang), operand));
}
@override
@@ -3701,6 +3707,7 @@
unionOfKinds(<ValueKind>[
ValueKinds.Expression,
ValueKinds.Generator,
+ ValueKinds.ProblemBuilder
]),
]));
debugEvent("UnaryPrefixExpression");
diff --git a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
index cc122ab..dd8e39b 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -5255,8 +5255,7 @@
if (!inferrer.isTopLevel && inferrer.isNonNullableByDefault) {
if (!inferrer.isAssignable(
inferrer.typeSchemaEnvironment.objectNonNullableRawType,
- expressionResult.inferredType,
- isStrongNullabilityMode: true)) {
+ expressionResult.inferredType)) {
return new ExpressionInferenceResult(
const DynamicType(),
inferrer.helper.buildProblem(
diff --git a/pkg/front_end/lib/src/fasta/kernel/type_labeler.dart b/pkg/front_end/lib/src/fasta/kernel/type_labeler.dart
index 69f2b57..6d3b442 100644
--- a/pkg/front_end/lib/src/fasta/kernel/type_labeler.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/type_labeler.dart
@@ -255,6 +255,12 @@
}
result.add(">");
}
+ if (classNode.name == 'Null' &&
+ classNode.enclosingLibrary.importUri.scheme == 'dart' &&
+ classNode.enclosingLibrary.importUri.path == 'core') {
+ // Don't print nullability on `Null`.
+ return;
+ }
addNullability(node.nullability);
}
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
index 018b077..bbaff28 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
@@ -16,6 +16,7 @@
NamedType,
NeverType,
Nullability,
+ Statement,
TreeNode,
TypeParameter,
TypeParameterType,
@@ -35,6 +36,8 @@
import '../kernel/forest.dart';
+import '../kernel/internal_ast.dart' show VariableDeclarationImpl;
+
import '../kernel/kernel_builder.dart'
show ClassHierarchyBuilder, ImplicitFieldType;
@@ -260,6 +263,14 @@
return factorType(typeEnvironment, from, what);
}
+ @override
+ bool isLocalVariableWithoutDeclaredType(VariableDeclaration variable) {
+ return variable is VariableDeclarationImpl &&
+ variable.parent is Statement &&
+ variable.isImplicitlyTyped &&
+ !variable.hasDeclaredInitializer;
+ }
+
// TODO(dmitryas): Consider checking for mutual subtypes instead of ==.
@override
bool isSameType(DartType type1, DartType type2) => type1 == type2;
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
index 3d30680..ac49df7 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
@@ -306,8 +306,14 @@
statement.expression != null) {
// If we are not inferring a type we can immediately check that the return
// is valid.
+ DartType wrappedType = type;
+ if (isAsync) {
+ wrappedType = inferrer.typeSchemaEnvironment.futureType(
+ inferrer.typeSchemaEnvironment.unfutureType(type),
+ Nullability.nonNullable);
+ }
Expression expression = inferrer.ensureAssignable(
- returnOrYieldContext, type, statement.expression,
+ returnOrYieldContext, wrappedType, statement.expression,
fileOffset: statement.fileOffset,
isReturnFromAsync: isAsync,
isVoidAllowed: true);
@@ -697,11 +703,8 @@
typeContext.classNode == coreTypes.doubleClass;
}
- bool isAssignable(DartType contextType, DartType expressionType,
- {bool isStrongNullabilityMode}) {
- isStrongNullabilityMode ??=
- isNonNullableByDefault && nnbdMode != NnbdMode.Weak;
- if (isStrongNullabilityMode) {
+ bool isAssignable(DartType contextType, DartType expressionType) {
+ if (isNonNullableByDefault) {
if (expressionType is DynamicType) return true;
return typeSchemaEnvironment
.performNullabilityAwareSubtypeCheck(expressionType, contextType)
diff --git a/pkg/front_end/lib/src/fasta/util/textual_outline.dart b/pkg/front_end/lib/src/fasta/util/textual_outline.dart
index 5ff9bc4..4f705d0 100644
--- a/pkg/front_end/lib/src/fasta/util/textual_outline.dart
+++ b/pkg/front_end/lib/src/fasta/util/textual_outline.dart
@@ -9,9 +9,6 @@
import 'package:_fe_analyzer_shared/src/parser/class_member_parser.dart'
show ClassMemberParser;
-import 'package:_fe_analyzer_shared/src/parser/declaration_kind.dart'
- show DeclarationKind;
-
import 'package:_fe_analyzer_shared/src/scanner/scanner.dart'
show ErrorToken, LanguageVersionToken, Scanner;
@@ -22,73 +19,335 @@
import 'package:_fe_analyzer_shared/src/scanner/token.dart' show Token;
-String textualOutline(List<int> rawBytes, {bool makeMoreReadable: false}) {
+// TODO: Sort imports.
+
+class _TextualOutlineState {
+ bool prevTokenKnown = false;
+ Token currentElementEnd;
+ List<String> currentChunk = new List<String>();
+ List<String> outputLines = new List<String>();
+
+ final bool performModelling;
+ String indent = "";
+ _TextualOutlineState(this.performModelling);
+}
+
+String textualOutline(List<int> rawBytes,
+ {bool throwOnUnexpected: false, bool performModelling: false}) {
// TODO(jensj): We need to specify the scanner settings to match that of the
// compiler!
Uint8List bytes = new Uint8List(rawBytes.length + 1);
bytes.setRange(0, rawBytes.length, rawBytes);
- StringBuffer sb = new StringBuffer();
+ // Idea:
+ // * Chunks are entities, e.g. whole classes, whole procedures etc.
+ // * It could also be an "unknown" batch of tokens.
+ // * currentChunk is a temporary buffer where we add chunks in a "run".
+ // * Depending on whether we know what the previous token (and thus chunk) is
+ // or not, and what the current token (and thus chunk) is, we either flush
+ // the currentChunk buffer or not.
+ // * The idea being, that if we add 3 chunks we know and then are about to add
+ // one we don't know, we can sort the 3 chunks we do know and output them.
+ // But when we go from unknown to known, we don't sort before outputting.
+
+ _TextualOutlineState state = new _TextualOutlineState(performModelling);
+
+ TokenPrinter tokenPrinter = new TokenPrinter();
Utf8BytesScanner scanner = new Utf8BytesScanner(bytes, includeComments: false,
languageVersionChanged:
(Scanner scanner, LanguageVersionToken languageVersion) {
- sb.writeln("// @dart = ${languageVersion.major}.${languageVersion.minor}");
+ flush(state, isSortable: false);
+ state.prevTokenKnown = false;
+ state.outputLines
+ .add("// @dart = ${languageVersion.major}.${languageVersion.minor}");
});
Token firstToken = scanner.tokenize();
- if (firstToken == null) return null;
- Token token = firstToken;
+ if (firstToken == null) {
+ if (throwOnUnexpected) throw "firstToken is null";
+ return null;
+ }
- EndOffsetListener listener = new EndOffsetListener();
+ TextualOutlineListener listener = new TextualOutlineListener();
ClassMemberParser classMemberParser = new ClassMemberParser(listener);
classMemberParser.parseUnit(firstToken);
- bool printed = false;
- int endOfLast = -1;
- bool addLinebreak = false;
+ Token token = firstToken;
while (token != null) {
if (token is ErrorToken) {
return null;
}
- if (addLinebreak) {
- sb.write("\n");
- } else if (printed && token.offset > endOfLast) {
- sb.write(" ");
- }
- addLinebreak = false;
-
- sb.write(token.lexeme);
- printed = true;
- endOfLast = token.end;
- if (makeMoreReadable) {
- if (token.lexeme == ";") {
- addLinebreak = true;
- } else if (token.endGroup != null &&
- (listener.nonClassEndOffsets.contains(token.endGroup.offset) ||
- listener.classEndOffsets.contains(token.endGroup.offset))) {
- addLinebreak = true;
- } else if (listener.nonClassEndOffsets.contains(token.offset) ||
- listener.classEndOffsets.contains(token.offset)) {
- addLinebreak = true;
- }
- }
-
if (token.isEof) break;
- if (token.endGroup != null &&
- listener.nonClassEndOffsets.contains(token.endGroup.offset)) {
- token = token.endGroup;
+ if (listener.classStartToFinish.containsKey(token)) {
+ if (state.prevTokenKnown) {
+ // TODO: Assert this instead.
+ if (!tokenPrinter.isEmpty) {
+ throw new StateError("Expected empty, was '${tokenPrinter.content}'");
+ }
+ } else if (!tokenPrinter.isEmpty) {
+ // We're ending a streak of unknown: Output, and flush,
+ // but it's not sortable.
+ tokenPrinter.addAndClearIfHasContent(state.currentChunk);
+ flush(state, isSortable: false);
+ }
+
+ Token currentClassEnd = listener.classStartToFinish[token];
+ String classContent = _textualizeClass(
+ listener, token, currentClassEnd, state,
+ throwOnUnexpected: throwOnUnexpected);
+ if (classContent == null) return null;
+ state.currentChunk.add(classContent);
+ token = currentClassEnd.next;
+ state.prevTokenKnown = true;
+ assert(tokenPrinter.isEmpty);
+ continue;
+ }
+
+ token = _textualizeNonClassEntriesInsideLoop(
+ listener, token, state, throwOnUnexpected, tokenPrinter);
+ if (token == null) return null;
+ }
+ _textualizeAfterLoop(state, tokenPrinter);
+ return state.outputLines.join("\n\n");
+}
+
+Token _textualizeNonClassEntriesInsideLoop(
+ TextualOutlineListener listener,
+ Token token,
+ _TextualOutlineState state,
+ bool throwOnUnexpected,
+ TokenPrinter tokenPrinter) {
+ if (listener.elementStartToFinish.containsKey(token)) {
+ if (state.currentElementEnd != null) {
+ if (throwOnUnexpected) throw "Element in element";
+ return null;
+ }
+ if (state.prevTokenKnown) {
+ if (!tokenPrinter.isEmpty) {
+ throw new StateError("Expected empty, was '${tokenPrinter.content}'");
+ }
+ } else if (!tokenPrinter.isEmpty) {
+ // We're ending a streak of unknown: Output, and flush,
+ // but it's not sortable.
+ tokenPrinter.addAndClearIfHasContent(state.currentChunk);
+ flush(state, isSortable: false);
+ }
+ state.currentElementEnd = listener.elementStartToFinish[token];
+ state.prevTokenKnown = true;
+ } else if (state.currentElementEnd == null &&
+ listener.metadataStartToFinish.containsKey(token)) {
+ if (state.prevTokenKnown) {
+ if (!tokenPrinter.isEmpty) {
+ throw new StateError("Expected empty, was '${tokenPrinter.content}'");
+ }
+ } else if (!tokenPrinter.isEmpty) {
+ // We're ending a streak of unknown: Output, and flush,
+ // but it's not sortable.
+ tokenPrinter.addAndClearIfHasContent(state.currentChunk);
+ flush(state, isSortable: false);
+ }
+ state.currentElementEnd = listener.metadataStartToFinish[token];
+ state.prevTokenKnown = true;
+ }
+
+ if (state.currentElementEnd == null && state.prevTokenKnown) {
+ // We're ending a streak of known stuff.
+ if (!tokenPrinter.isEmpty) {
+ throw new StateError("Expected empty, was '${tokenPrinter.content}'");
+ }
+ flush(state, isSortable: true);
+ state.prevTokenKnown = false;
+ } else {
+ if (state.currentElementEnd == null) {
+ if (state.prevTokenKnown) {
+ // known -> unknown.
+ throw "This case was apparently not handled above.";
+ } else {
+ // OK: Streak of unknown.
+ }
} else {
- token = token.next;
+ if (state.prevTokenKnown) {
+ // OK: Streak of known.
+ } else {
+ // unknown -> known: This should have been flushed above.
+ if (!tokenPrinter.isEmpty) {
+ throw new StateError("Expected empty, was '${tokenPrinter.content}'");
+ }
+ }
}
}
- return sb.toString();
+ tokenPrinter.print(token);
+
+ if (token == state.currentElementEnd) {
+ state.currentElementEnd = null;
+ tokenPrinter.addAndClearIfHasContent(state.currentChunk);
+ }
+
+ if (token.endGroup != null &&
+ listener.nonClassEndOffsets.contains(token.endGroup.offset)) {
+ token = token.endGroup;
+ tokenPrinter.nextTokenIsEndGroup = true;
+ } else {
+ token = token.next;
+ }
+ return token;
+}
+
+void _textualizeAfterLoop(
+ _TextualOutlineState state, TokenPrinter tokenPrinter) {
+ // We're done, so we're logically at an unknown token.
+ if (state.prevTokenKnown) {
+ // We're ending a streak of known stuff.
+ if (!tokenPrinter.isEmpty) {
+ throw new StateError("Expected empty, was '${tokenPrinter.content}'");
+ }
+ flush(state, isSortable: true);
+ state.prevTokenKnown = false;
+ } else {
+ // Streak of unknown.
+ tokenPrinter.addAndClearIfHasContent(state.currentChunk);
+ flush(state, isSortable: false);
+ state.prevTokenKnown = false;
+ }
+}
+
+void flush(_TextualOutlineState state, {bool isSortable}) {
+ assert(isSortable != null);
+ if (state.currentChunk.isEmpty) return;
+ if (isSortable) {
+ state.currentChunk = mergeAndSort(state.currentChunk, state.indent,
+ isModelling: state.performModelling);
+ }
+ if (state.indent == "") {
+ state.outputLines.addAll(state.currentChunk);
+ } else {
+ for (int i = 0; i < state.currentChunk.length; i++) {
+ state.outputLines.add("${state.indent}${state.currentChunk[i]}");
+ }
+ }
+ state.currentChunk.clear();
+}
+
+List<String> mergeAndSort(List<String> data, String indent,
+ {bool isModelling}) {
+ assert(isModelling != null);
+ // If not modelling, don't sort.
+ if (!isModelling) return data;
+
+ bool hasAnnotations = false;
+ for (int i = 0; i < data.length - 1; i++) {
+ String element = data[i];
+ if (element.startsWith("@")) {
+ hasAnnotations = true;
+ break;
+ }
+ }
+ if (!hasAnnotations) {
+ data.sort();
+ return data;
+ }
+
+ // There's annotations: Merge them with the owner.
+ List<String> merged = new List<String>();
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < data.length; i++) {
+ String element = data[i];
+ if (element.startsWith("@")) {
+ if (sb.length > 0) sb.write(indent);
+ sb.writeln(element);
+ } else {
+ if (sb.length > 0) sb.write(indent);
+ sb.write(element);
+ merged.add(sb.toString());
+ sb.clear();
+ }
+ }
+ if (sb.length > 0) {
+ merged.add(sb.toString());
+ sb.clear();
+ }
+
+ merged.sort();
+ return merged;
+}
+
+class TokenPrinter {
+ bool nextTokenIsEndGroup = false;
+ int _endOfLast = -1;
+ StringBuffer _sb = new StringBuffer();
+
+ String get content => _sb.toString();
+
+ bool get isEmpty => _sb.isEmpty;
+
+ void clear() {
+ _endOfLast = -1;
+ _sb.clear();
+ }
+
+ void addAndClearIfHasContent(List<String> list) {
+ if (_sb.length > 0) {
+ list.add(_sb.toString());
+ clear();
+ }
+ }
+
+ void print(Token token) {
+ if (_sb.isNotEmpty && (token.offset > _endOfLast || nextTokenIsEndGroup)) {
+ _sb.write(" ");
+ }
+
+ _sb.write(token.lexeme);
+ _endOfLast = token.end;
+ nextTokenIsEndGroup = false;
+ }
+
+ String toString() {
+ throw new UnsupportedError("toString");
+ }
+}
+
+String _textualizeClass(TextualOutlineListener listener, Token beginToken,
+ Token endToken, _TextualOutlineState originalState,
+ {bool throwOnUnexpected: false, bool model: false}) {
+ Token token = beginToken;
+ TokenPrinter tokenPrinter = new TokenPrinter();
+ // Class header.
+ while (token != endToken) {
+ tokenPrinter.print(token);
+ if (token.endGroup == endToken) {
+ token = token.next;
+ break;
+ }
+ token = token.next;
+ }
+ _TextualOutlineState state =
+ new _TextualOutlineState(originalState.performModelling);
+ tokenPrinter.addAndClearIfHasContent(state.currentChunk);
+ flush(state, isSortable: false);
+
+ state.indent = " ";
+ while (token != endToken) {
+ token = _textualizeNonClassEntriesInsideLoop(
+ listener, token, state, throwOnUnexpected, tokenPrinter);
+ if (token == null) return null;
+ }
+ _textualizeAfterLoop(state, tokenPrinter);
+
+ state.indent = "";
+ tokenPrinter.nextTokenIsEndGroup = true;
+ tokenPrinter.print(token);
+ tokenPrinter.addAndClearIfHasContent(state.currentChunk);
+ flush(state, isSortable: false);
+ return state.outputLines.join("\n");
}
main(List<String> args) {
File f = new File(args[0]);
- String outline = textualOutline(f.readAsBytesSync(), makeMoreReadable: true);
+ String outline = textualOutline(f.readAsBytesSync(),
+ throwOnUnexpected: true, performModelling: true);
if (args.length > 1 && args[1] == "--overwrite") {
f.writeAsStringSync(outline);
} else {
@@ -96,35 +355,88 @@
}
}
-class EndOffsetListener extends DirectiveListener {
+class TextualOutlineListener extends DirectiveListener {
Set<int> nonClassEndOffsets = new Set<int>();
- Set<int> classEndOffsets = new Set<int>();
+ Map<Token, Token> classStartToFinish = {};
+ Map<Token, Token> elementStartToFinish = {};
+ Map<Token, Token> metadataStartToFinish = {};
@override
void endClassMethod(Token getOrSet, Token beginToken, Token beginParam,
Token beginInitializers, Token endToken) {
nonClassEndOffsets.add(endToken.offset);
+ elementStartToFinish[beginToken] = endToken;
}
@override
void endTopLevelMethod(Token beginToken, Token getOrSet, Token endToken) {
nonClassEndOffsets.add(endToken.offset);
+ elementStartToFinish[beginToken] = endToken;
}
@override
void endClassFactoryMethod(
Token beginToken, Token factoryKeyword, Token endToken) {
nonClassEndOffsets.add(endToken.offset);
- }
-
- @override
- void endClassOrMixinBody(
- DeclarationKind kind, int memberCount, Token beginToken, Token endToken) {
- classEndOffsets.add(endToken.offset);
+ elementStartToFinish[beginToken] = endToken;
}
@override
void handleNativeFunctionBodySkipped(Token nativeToken, Token semicolon) {
// Allow native functions.
}
+
+ @override
+ void endClassFields(Token staticToken, Token covariantToken, Token lateToken,
+ Token varFinalOrConst, int count, Token beginToken, Token endToken) {
+ elementStartToFinish[beginToken] = endToken;
+ }
+
+ @override
+ void endTopLevelFields(
+ Token staticToken,
+ Token covariantToken,
+ Token lateToken,
+ Token varFinalOrConst,
+ int count,
+ Token beginToken,
+ Token endToken) {
+ elementStartToFinish[beginToken] = endToken;
+ }
+
+ void endFunctionTypeAlias(
+ Token typedefKeyword, Token equals, Token endToken) {
+ elementStartToFinish[typedefKeyword] = endToken;
+ }
+
+ void endEnum(Token enumKeyword, Token leftBrace, int count) {
+ elementStartToFinish[enumKeyword] = leftBrace.endGroup;
+ }
+
+ // @override
+ // void endLibraryName(Token libraryKeyword, Token semicolon) {
+ // elementStartToFinish[libraryKeyword] = semicolon;
+ // }
+
+ @override
+ void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) {
+ // Metadata's endToken is the one *after* the actual end of the metadata.
+ metadataStartToFinish[beginToken] = endToken.previous;
+ }
+
+ @override
+ void endClassDeclaration(Token beginToken, Token endToken) {
+ classStartToFinish[beginToken] = endToken;
+ }
+
+ @override
+ void endMixinDeclaration(Token mixinKeyword, Token endToken) {
+ classStartToFinish[mixinKeyword] = endToken;
+ }
+
+ @override
+ void endExtensionDeclaration(
+ Token extensionKeyword, Token onKeyword, Token endToken) {
+ classStartToFinish[extensionKeyword] = endToken;
+ }
}
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_41597.dart b/pkg/front_end/parser_testcases/nnbd/issue_41597.dart
new file mode 100644
index 0000000..b75f50a
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/issue_41597.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+bool x;
+bool x;
+
+errors() {
+ print(x);
+ print(x!);
+ print(!x);
+}
+
+class C {
+ C.c0() : super();
+ C.c1() : super()!;
+}
+
+main() {}
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_41597.dart.expect b/pkg/front_end/parser_testcases/nnbd/issue_41597.dart.expect
new file mode 100644
index 0000000..b56f22d
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/issue_41597.dart.expect
@@ -0,0 +1,146 @@
+beginCompilationUnit(bool)
+ beginMetadataStar(bool)
+ endMetadataStar(0)
+ beginTopLevelMember(bool)
+ handleIdentifier(bool, typeReference)
+ handleNoTypeArguments(x)
+ handleType(bool, null)
+ handleIdentifier(x, topLevelVariableDeclaration)
+ handleNoFieldInitializer(;)
+ endTopLevelFields(null, null, null, null, 1, bool, ;)
+endTopLevelDeclaration(bool)
+beginMetadataStar(bool)
+endMetadataStar(0)
+beginTopLevelMember(bool)
+ handleIdentifier(bool, typeReference)
+ handleNoTypeArguments(x)
+ handleType(bool, null)
+ handleIdentifier(x, topLevelVariableDeclaration)
+ handleNoFieldInitializer(;)
+endTopLevelFields(null, null, null, null, 1, bool, ;)
+endTopLevelDeclaration(errors)
+beginMetadataStar(errors)
+endMetadataStar(0)
+beginTopLevelMember(errors)
+beginTopLevelMethod(;, null)
+ handleNoType(;)
+ handleIdentifier(errors, topLevelFunctionDeclaration)
+ handleNoTypeVariables(()
+ beginFormalParameters((, MemberKind.TopLevelMethod)
+ endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+ handleAsyncModifier(null, null)
+ beginBlockFunctionBody({)
+ handleIdentifier(print, expression)
+ handleNoTypeArguments(()
+ beginArguments(()
+ handleIdentifier(x, expression)
+ handleNoTypeArguments())
+ handleNoArguments())
+ handleSend(x, ))
+ endArguments(1, (, ))
+ handleSend(print, ;)
+ handleExpressionStatement(;)
+ handleIdentifier(print, expression)
+ handleNoTypeArguments(()
+ beginArguments(()
+ handleIdentifier(x, expression)
+ handleNoTypeArguments(!)
+ handleNoArguments(!)
+ handleSend(x, !)
+ handleNonNullAssertExpression(!)
+ endArguments(1, (, ))
+ handleSend(print, ;)
+ handleExpressionStatement(;)
+ handleIdentifier(print, expression)
+ handleNoTypeArguments(()
+ beginArguments(()
+ handleIdentifier(x, expression)
+ handleNoTypeArguments())
+ handleNoArguments())
+ handleSend(x, ))
+ handleUnaryPrefixExpression(!)
+ endArguments(1, (, ))
+ handleSend(print, ;)
+ handleExpressionStatement(;)
+ endBlockFunctionBody(3, {, })
+endTopLevelMethod(errors, null, })
+endTopLevelDeclaration(class)
+beginMetadataStar(class)
+endMetadataStar(0)
+beginClassOrNamedMixinApplicationPrelude(class)
+handleIdentifier(C, classOrMixinDeclaration)
+handleNoTypeVariables({)
+beginClassDeclaration(class, null, C)
+ handleNoType(C)
+ handleClassExtends(null)
+ handleClassNoWithClause()
+ handleClassOrMixinImplements(null, 0)
+ handleClassHeader(class, class, null)
+ beginClassOrMixinBody(DeclarationKind.Class, {)
+ beginMetadataStar(C)
+ endMetadataStar(0)
+ beginMember()
+ beginMethod(null, null, null, null, null, C)
+ handleNoType({)
+ handleIdentifier(C, methodDeclaration)
+ handleIdentifier(c0, methodDeclarationContinuation)
+ handleQualified(.)
+ handleNoTypeVariables(()
+ beginFormalParameters((, MemberKind.NonStaticMethod)
+ endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+ beginInitializers(:)
+ beginInitializer(super)
+ handleSuperExpression(super, expression)
+ handleNoTypeArguments(()
+ beginArguments(()
+ endArguments(0, (, ))
+ handleSend(super, ;)
+ endInitializer(;)
+ endInitializers(1, :, ;)
+ handleAsyncModifier(null, null)
+ handleEmptyFunctionBody(;)
+ endClassConstructor(null, C, (, :, ;)
+ endMember()
+ beginMetadataStar(C)
+ endMetadataStar(0)
+ beginMember()
+ beginMethod(null, null, null, null, null, C)
+ handleNoType(;)
+ handleIdentifier(C, methodDeclaration)
+ handleIdentifier(c1, methodDeclarationContinuation)
+ handleQualified(.)
+ handleNoTypeVariables(()
+ beginFormalParameters((, MemberKind.NonStaticMethod)
+ endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+ beginInitializers(:)
+ beginInitializer(super)
+ handleSuperExpression(super, expression)
+ handleNoTypeArguments(()
+ beginArguments(()
+ endArguments(0, (, ))
+ handleSend(super, !)
+ handleNonNullAssertExpression(!)
+ endInitializer(;)
+ endInitializers(1, :, ;)
+ handleAsyncModifier(null, null)
+ handleEmptyFunctionBody(;)
+ endClassConstructor(null, C, (, :, ;)
+ endMember()
+ endClassOrMixinBody(DeclarationKind.Class, 2, {, })
+endClassDeclaration(class, })
+endTopLevelDeclaration(main)
+beginMetadataStar(main)
+endMetadataStar(0)
+beginTopLevelMember(main)
+beginTopLevelMethod(}, null)
+ handleNoType(})
+ handleIdentifier(main, topLevelFunctionDeclaration)
+ handleNoTypeVariables(()
+ beginFormalParameters((, MemberKind.TopLevelMethod)
+ endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+ handleAsyncModifier(null, null)
+ beginBlockFunctionBody({)
+ endBlockFunctionBody(0, {, })
+endTopLevelMethod(main, null, })
+endTopLevelDeclaration()
+endCompilationUnit(5, )
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_41597.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/issue_41597.dart.intertwined.expect
new file mode 100644
index 0000000..ac4681d
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/issue_41597.dart.intertwined.expect
@@ -0,0 +1,337 @@
+parseUnit(bool)
+ skipErrorTokens(bool)
+ listener: beginCompilationUnit(bool)
+ syntheticPreviousToken(bool)
+ parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+ parseMetadataStar()
+ listener: beginMetadataStar(bool)
+ listener: endMetadataStar(0)
+ parseTopLevelMemberImpl()
+ listener: beginTopLevelMember(bool)
+ parseFields(, null, null, null, null, null, , Instance of 'SimpleType', x, DeclarationKind.TopLevel, null)
+ listener: handleIdentifier(bool, typeReference)
+ listener: handleNoTypeArguments(x)
+ listener: handleType(bool, null)
+ ensureIdentifier(bool, topLevelVariableDeclaration)
+ listener: handleIdentifier(x, topLevelVariableDeclaration)
+ parseFieldInitializerOpt(x, x, null, null, DeclarationKind.TopLevel, null)
+ listener: handleNoFieldInitializer(;)
+ listener: endTopLevelFields(null, null, null, null, 1, bool, ;)
+ listener: endTopLevelDeclaration(bool)
+ parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+ parseMetadataStar(;)
+ listener: beginMetadataStar(bool)
+ listener: endMetadataStar(0)
+ parseTopLevelMemberImpl(;)
+ listener: beginTopLevelMember(bool)
+ parseFields(;, null, null, null, null, null, ;, Instance of 'SimpleType', x, DeclarationKind.TopLevel, null)
+ listener: handleIdentifier(bool, typeReference)
+ listener: handleNoTypeArguments(x)
+ listener: handleType(bool, null)
+ ensureIdentifier(bool, topLevelVariableDeclaration)
+ listener: handleIdentifier(x, topLevelVariableDeclaration)
+ parseFieldInitializerOpt(x, x, null, null, DeclarationKind.TopLevel, null)
+ listener: handleNoFieldInitializer(;)
+ listener: endTopLevelFields(null, null, null, null, 1, bool, ;)
+ listener: endTopLevelDeclaration(errors)
+ parseTopLevelDeclarationImpl(;, Instance of 'DirectiveContext')
+ parseMetadataStar(;)
+ listener: beginMetadataStar(errors)
+ listener: endMetadataStar(0)
+ parseTopLevelMemberImpl(;)
+ listener: beginTopLevelMember(errors)
+ parseTopLevelMethod(;, null, ;, Instance of 'NoType', null, errors)
+ listener: beginTopLevelMethod(;, null)
+ listener: handleNoType(;)
+ ensureIdentifier(;, topLevelFunctionDeclaration)
+ listener: handleIdentifier(errors, topLevelFunctionDeclaration)
+ parseMethodTypeVar(errors)
+ listener: handleNoTypeVariables(()
+ parseGetterOrFormalParameters(errors, errors, false, MemberKind.TopLevelMethod)
+ parseFormalParameters(errors, MemberKind.TopLevelMethod)
+ parseFormalParametersRest((, MemberKind.TopLevelMethod)
+ listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+ listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+ parseAsyncModifierOpt())
+ listener: handleAsyncModifier(null, null)
+ inPlainSync()
+ parseFunctionBody(), false, false)
+ listener: beginBlockFunctionBody({)
+ notEofOrValue(}, print)
+ parseStatement({)
+ parseStatementX({)
+ parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+ looksLikeLocalFunction(print)
+ parseExpressionStatement({)
+ parseExpression({)
+ parsePrecedenceExpression({, 1, true)
+ parseUnaryExpression({, true)
+ parsePrimary({, expression)
+ parseSendOrFunctionLiteral({, expression)
+ looksLikeFunctionBody(;)
+ parseSend({, expression)
+ ensureIdentifier({, expression)
+ listener: handleIdentifier(print, expression)
+ listener: handleNoTypeArguments(()
+ parseArgumentsOpt(print)
+ parseArguments(print)
+ parseArgumentsRest(()
+ listener: beginArguments(()
+ parseExpression(()
+ parsePrecedenceExpression((, 1, true)
+ parseUnaryExpression((, true)
+ parsePrimary((, expression)
+ parseSendOrFunctionLiteral((, expression)
+ parseSend((, expression)
+ ensureIdentifier((, expression)
+ listener: handleIdentifier(x, expression)
+ listener: handleNoTypeArguments())
+ parseArgumentsOpt(x)
+ listener: handleNoArguments())
+ listener: handleSend(x, ))
+ listener: endArguments(1, (, ))
+ listener: handleSend(print, ;)
+ ensureSemicolon())
+ listener: handleExpressionStatement(;)
+ notEofOrValue(}, print)
+ parseStatement(;)
+ parseStatementX(;)
+ parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+ looksLikeLocalFunction(print)
+ parseExpressionStatement(;)
+ parseExpression(;)
+ parsePrecedenceExpression(;, 1, true)
+ parseUnaryExpression(;, true)
+ parsePrimary(;, expression)
+ parseSendOrFunctionLiteral(;, expression)
+ looksLikeFunctionBody(;)
+ parseSend(;, expression)
+ ensureIdentifier(;, expression)
+ listener: handleIdentifier(print, expression)
+ listener: handleNoTypeArguments(()
+ parseArgumentsOpt(print)
+ parseArguments(print)
+ parseArgumentsRest(()
+ listener: beginArguments(()
+ parseExpression(()
+ parsePrecedenceExpression((, 1, true)
+ parseUnaryExpression((, true)
+ parsePrimary((, expression)
+ parseSendOrFunctionLiteral((, expression)
+ parseSend((, expression)
+ ensureIdentifier((, expression)
+ listener: handleIdentifier(x, expression)
+ listener: handleNoTypeArguments(!)
+ parseArgumentsOpt(x)
+ listener: handleNoArguments(!)
+ listener: handleSend(x, !)
+ listener: handleNonNullAssertExpression(!)
+ listener: endArguments(1, (, ))
+ listener: handleSend(print, ;)
+ ensureSemicolon())
+ listener: handleExpressionStatement(;)
+ notEofOrValue(}, print)
+ parseStatement(;)
+ parseStatementX(;)
+ parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+ looksLikeLocalFunction(print)
+ parseExpressionStatement(;)
+ parseExpression(;)
+ parsePrecedenceExpression(;, 1, true)
+ parseUnaryExpression(;, true)
+ parsePrimary(;, expression)
+ parseSendOrFunctionLiteral(;, expression)
+ looksLikeFunctionBody(;)
+ parseSend(;, expression)
+ ensureIdentifier(;, expression)
+ listener: handleIdentifier(print, expression)
+ listener: handleNoTypeArguments(()
+ parseArgumentsOpt(print)
+ parseArguments(print)
+ parseArgumentsRest(()
+ listener: beginArguments(()
+ parseExpression(()
+ parsePrecedenceExpression((, 1, true)
+ parseUnaryExpression((, true)
+ parsePrecedenceExpression(!, 16, true)
+ parseUnaryExpression(!, true)
+ parsePrimary(!, expression)
+ parseSendOrFunctionLiteral(!, expression)
+ parseSend(!, expression)
+ ensureIdentifier(!, expression)
+ listener: handleIdentifier(x, expression)
+ listener: handleNoTypeArguments())
+ parseArgumentsOpt(x)
+ listener: handleNoArguments())
+ listener: handleSend(x, ))
+ listener: handleUnaryPrefixExpression(!)
+ listener: endArguments(1, (, ))
+ listener: handleSend(print, ;)
+ ensureSemicolon())
+ listener: handleExpressionStatement(;)
+ notEofOrValue(}, })
+ listener: endBlockFunctionBody(3, {, })
+ listener: endTopLevelMethod(errors, null, })
+ listener: endTopLevelDeclaration(class)
+ parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+ parseMetadataStar(})
+ listener: beginMetadataStar(class)
+ listener: endMetadataStar(0)
+ parseTopLevelKeywordDeclaration(}, class, Instance of 'DirectiveContext')
+ parseClassDeclarationModifiers(}, class)
+ parseClassOrNamedMixinApplication(null, class)
+ listener: beginClassOrNamedMixinApplicationPrelude(class)
+ ensureIdentifier(class, classOrMixinDeclaration)
+ listener: handleIdentifier(C, classOrMixinDeclaration)
+ listener: handleNoTypeVariables({)
+ listener: beginClassDeclaration(class, null, C)
+ parseClass(C, class, class, C)
+ parseClassHeaderOpt(C, class, class)
+ parseClassExtendsOpt(C)
+ listener: handleNoType(C)
+ listener: handleClassExtends(null)
+ parseWithClauseOpt(C)
+ listener: handleClassNoWithClause()
+ parseClassOrMixinImplementsOpt(C)
+ listener: handleClassOrMixinImplements(null, 0)
+ listener: handleClassHeader(class, class, null)
+ parseClassOrMixinOrExtensionBody(C, DeclarationKind.Class, C)
+ listener: beginClassOrMixinBody(DeclarationKind.Class, {)
+ notEofOrValue(}, C)
+ parseClassOrMixinOrExtensionMemberImpl({, DeclarationKind.Class, C)
+ parseMetadataStar({)
+ listener: beginMetadataStar(C)
+ listener: endMetadataStar(0)
+ listener: beginMember()
+ parseMethod({, null, null, null, null, null, {, Instance of 'NoType', null, C, DeclarationKind.Class, C)
+ listener: beginMethod(null, null, null, null, null, C)
+ listener: handleNoType({)
+ ensureIdentifier({, methodDeclaration)
+ listener: handleIdentifier(C, methodDeclaration)
+ parseQualifiedRestOpt(C, methodDeclarationContinuation)
+ parseQualifiedRest(C, methodDeclarationContinuation)
+ ensureIdentifier(., methodDeclarationContinuation)
+ listener: handleIdentifier(c0, methodDeclarationContinuation)
+ listener: handleQualified(.)
+ parseMethodTypeVar(c0)
+ listener: handleNoTypeVariables(()
+ parseGetterOrFormalParameters(c0, C, false, MemberKind.NonStaticMethod)
+ parseFormalParameters(c0, MemberKind.NonStaticMethod)
+ parseFormalParametersRest((, MemberKind.NonStaticMethod)
+ listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+ listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+ parseInitializersOpt())
+ parseInitializers(:)
+ listener: beginInitializers(:)
+ parseInitializer(:)
+ listener: beginInitializer(super)
+ parseSuperInitializerExpression(:)
+ parseInitializerExpressionRest(:)
+ parseExpression(:)
+ parsePrecedenceExpression(:, 1, true)
+ parseUnaryExpression(:, true)
+ parsePrimary(:, expression)
+ parseSuperExpression(:, expression)
+ listener: handleSuperExpression(super, expression)
+ listener: handleNoTypeArguments(()
+ parseArguments(super)
+ parseArgumentsRest(()
+ listener: beginArguments(()
+ listener: endArguments(0, (, ))
+ listener: handleSend(super, ;)
+ listener: endInitializer(;)
+ listener: endInitializers(1, :, ;)
+ parseAsyncModifierOpt())
+ listener: handleAsyncModifier(null, null)
+ inPlainSync()
+ inPlainSync()
+ parseFunctionBody(), false, true)
+ listener: handleEmptyFunctionBody(;)
+ listener: endClassConstructor(null, C, (, :, ;)
+ listener: endMember()
+ notEofOrValue(}, C)
+ parseClassOrMixinOrExtensionMemberImpl(;, DeclarationKind.Class, C)
+ parseMetadataStar(;)
+ listener: beginMetadataStar(C)
+ listener: endMetadataStar(0)
+ listener: beginMember()
+ parseMethod(;, null, null, null, null, null, ;, Instance of 'NoType', null, C, DeclarationKind.Class, C)
+ listener: beginMethod(null, null, null, null, null, C)
+ listener: handleNoType(;)
+ ensureIdentifier(;, methodDeclaration)
+ listener: handleIdentifier(C, methodDeclaration)
+ parseQualifiedRestOpt(C, methodDeclarationContinuation)
+ parseQualifiedRest(C, methodDeclarationContinuation)
+ ensureIdentifier(., methodDeclarationContinuation)
+ listener: handleIdentifier(c1, methodDeclarationContinuation)
+ listener: handleQualified(.)
+ parseMethodTypeVar(c1)
+ listener: handleNoTypeVariables(()
+ parseGetterOrFormalParameters(c1, C, false, MemberKind.NonStaticMethod)
+ parseFormalParameters(c1, MemberKind.NonStaticMethod)
+ parseFormalParametersRest((, MemberKind.NonStaticMethod)
+ listener: beginFormalParameters((, MemberKind.NonStaticMethod)
+ listener: endFormalParameters(0, (, ), MemberKind.NonStaticMethod)
+ parseInitializersOpt())
+ parseInitializers(:)
+ listener: beginInitializers(:)
+ parseInitializer(:)
+ listener: beginInitializer(super)
+ parseSuperInitializerExpression(:)
+ parseInitializerExpressionRest(:)
+ parseExpression(:)
+ parsePrecedenceExpression(:, 1, true)
+ parseUnaryExpression(:, true)
+ parsePrimary(:, expression)
+ parseSuperExpression(:, expression)
+ listener: handleSuperExpression(super, expression)
+ listener: handleNoTypeArguments(()
+ parseArguments(super)
+ parseArgumentsRest(()
+ listener: beginArguments(()
+ listener: endArguments(0, (, ))
+ listener: handleSend(super, !)
+ listener: handleNonNullAssertExpression(!)
+ listener: endInitializer(;)
+ listener: endInitializers(1, :, ;)
+ parseAsyncModifierOpt(!)
+ listener: handleAsyncModifier(null, null)
+ inPlainSync()
+ inPlainSync()
+ parseFunctionBody(!, false, true)
+ listener: handleEmptyFunctionBody(;)
+ listener: endClassConstructor(null, C, (, :, ;)
+ listener: endMember()
+ notEofOrValue(}, })
+ listener: endClassOrMixinBody(DeclarationKind.Class, 2, {, })
+ listener: endClassDeclaration(class, })
+ listener: endTopLevelDeclaration(main)
+ parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
+ parseMetadataStar(})
+ listener: beginMetadataStar(main)
+ listener: endMetadataStar(0)
+ parseTopLevelMemberImpl(})
+ listener: beginTopLevelMember(main)
+ parseTopLevelMethod(}, null, }, Instance of 'NoType', null, main)
+ listener: beginTopLevelMethod(}, null)
+ listener: handleNoType(})
+ ensureIdentifier(}, topLevelFunctionDeclaration)
+ listener: handleIdentifier(main, topLevelFunctionDeclaration)
+ parseMethodTypeVar(main)
+ listener: handleNoTypeVariables(()
+ parseGetterOrFormalParameters(main, main, false, MemberKind.TopLevelMethod)
+ parseFormalParameters(main, MemberKind.TopLevelMethod)
+ parseFormalParametersRest((, MemberKind.TopLevelMethod)
+ listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+ listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+ parseAsyncModifierOpt())
+ listener: handleAsyncModifier(null, null)
+ inPlainSync()
+ parseFunctionBody(), false, false)
+ listener: beginBlockFunctionBody({)
+ notEofOrValue(}, })
+ listener: endBlockFunctionBody(0, {, })
+ listener: endTopLevelMethod(main, null, })
+ listener: endTopLevelDeclaration()
+ reportAllErrorTokens(bool)
+ listener: endCompilationUnit(5, )
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_41597.dart.parser.expect b/pkg/front_end/parser_testcases/nnbd/issue_41597.dart.parser.expect
new file mode 100644
index 0000000..2261909
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/issue_41597.dart.parser.expect
@@ -0,0 +1,33 @@
+bool x;
+bool x;
+
+errors() {
+print(x);
+print(x!);
+print(!x);
+}
+
+class C {
+C.c0() : super();
+C.c1() : super()!;
+}
+
+main() {}
+
+
+bool[StringToken] x[StringToken];[SimpleToken]
+bool[StringToken] x[StringToken];[SimpleToken]
+
+errors[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+print[StringToken]([BeginToken]x[StringToken])[SimpleToken];[SimpleToken]
+print[StringToken]([BeginToken]x[StringToken]![SimpleToken])[SimpleToken];[SimpleToken]
+print[StringToken]([BeginToken]![SimpleToken]x[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+class[KeywordToken] C[StringToken] {[BeginToken]
+C[StringToken].[SimpleToken]c0[StringToken]([BeginToken])[SimpleToken] :[SimpleToken] super[KeywordToken]([BeginToken])[SimpleToken];[SimpleToken]
+C[StringToken].[SimpleToken]c1[StringToken]([BeginToken])[SimpleToken] :[SimpleToken] super[KeywordToken]([BeginToken])[SimpleToken]![SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/nnbd/issue_41597.dart.scanner.expect b/pkg/front_end/parser_testcases/nnbd/issue_41597.dart.scanner.expect
new file mode 100644
index 0000000..2261909
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/issue_41597.dart.scanner.expect
@@ -0,0 +1,33 @@
+bool x;
+bool x;
+
+errors() {
+print(x);
+print(x!);
+print(!x);
+}
+
+class C {
+C.c0() : super();
+C.c1() : super()!;
+}
+
+main() {}
+
+
+bool[StringToken] x[StringToken];[SimpleToken]
+bool[StringToken] x[StringToken];[SimpleToken]
+
+errors[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+print[StringToken]([BeginToken]x[StringToken])[SimpleToken];[SimpleToken]
+print[StringToken]([BeginToken]x[StringToken]![SimpleToken])[SimpleToken];[SimpleToken]
+print[StringToken]([BeginToken]![SimpleToken]x[StringToken])[SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+class[KeywordToken] C[StringToken] {[BeginToken]
+C[StringToken].[SimpleToken]c0[StringToken]([BeginToken])[SimpleToken] :[SimpleToken] super[KeywordToken]([BeginToken])[SimpleToken];[SimpleToken]
+C[StringToken].[SimpleToken]c1[StringToken]([BeginToken])[SimpleToken] :[SimpleToken] super[KeywordToken]([BeginToken])[SimpleToken]![SimpleToken];[SimpleToken]
+}[SimpleToken]
+
+main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/test/crashing_test_case_minimizer.dart b/pkg/front_end/test/crashing_test_case_minimizer.dart
index 797bded..09bedc5 100644
--- a/pkg/front_end/test/crashing_test_case_minimizer.dart
+++ b/pkg/front_end/test/crashing_test_case_minimizer.dart
@@ -15,18 +15,17 @@
import 'package:_fe_analyzer_shared/src/scanner/token.dart' show Token;
+import 'package:dev_compiler/src/kernel/target.dart' show DevCompilerTarget;
+
import 'package:front_end/src/api_prototype/compiler_options.dart'
show CompilerOptions, DiagnosticMessage;
-import 'package:front_end/src/api_prototype/memory_file_system.dart'
- show MemoryFileSystem;
+import 'package:front_end/src/api_prototype/file_system.dart'
+ show FileSystem, FileSystemEntity, FileSystemException;
import 'package:front_end/src/base/processed_options.dart'
show ProcessedOptions;
-import 'package:front_end/src/compute_platform_binaries_location.dart'
- show computePlatformBinariesLocation;
-
import 'package:front_end/src/fasta/compiler_context.dart' show CompilerContext;
import 'package:front_end/src/fasta/incremental_compiler.dart'
@@ -34,24 +33,51 @@
import 'package:kernel/ast.dart' show Component;
+import 'package:kernel/target/targets.dart' show Target, TargetFlags;
+
+import "package:vm/target/flutter.dart" show FlutterTarget;
+
+import "package:vm/target/vm.dart" show VmTarget;
+
+import 'incremental_load_from_dill_suite.dart' show getOptions;
+
import 'parser_test_listener.dart' show ParserTestListener;
import 'parser_suite.dart' as parser_suite;
-import 'incremental_load_from_dill_suite.dart' show getOptions;
-
-Uri sdkRoot = computePlatformBinariesLocation(forceBuildDir: true);
-Uri base = Uri.parse("org-dartlang-test:///");
-Uri sdkSummary = base.resolve("vm_platform.dill");
-Uri platformUri = sdkRoot.resolve("vm_platform_strong.dill");
+final FakeFileSystem fs = new FakeFileSystem();
+Uri mainUri;
+Uri platformUri;
+bool nnbd = false;
+bool widgetTransformation = false;
+List<Uri> invalidate = [];
+String targetString = "VM";
+String expectedCrashLine;
+bool byteDelete = false;
main(List<String> arguments) async {
String filename;
- bool nnbd = false;
for (String arg in arguments) {
if (arg.startsWith("--")) {
if (arg == "--nnbd") {
nnbd = true;
+ } else if (arg.startsWith("--platform=")) {
+ String platform = arg.substring("--platform=".length);
+ platformUri = Uri.base.resolve(platform);
+ } else if (arg.startsWith("--invalidate=")) {
+ for (String s in arg.substring("--invalidate=".length).split(",")) {
+ invalidate.add(Uri.base.resolve(s));
+ }
+ } else if (arg.startsWith("--widgetTransformation")) {
+ widgetTransformation = true;
+ } else if (arg.startsWith("--target=VM")) {
+ targetString = "VM";
+ } else if (arg.startsWith("--target=flutter")) {
+ targetString = "flutter";
+ } else if (arg.startsWith("--target=ddc")) {
+ targetString = "ddc";
+ } else if (arg == "--byteDelete") {
+ byteDelete = true;
} else {
throw "Unknown option $arg";
}
@@ -62,71 +88,136 @@
filename = arg;
}
}
+ if (platformUri == null) {
+ throw "No platform given. Use --platform=/path/to/platform.dill";
+ }
+ if (!new File.fromUri(platformUri).existsSync()) {
+ throw "The platform file '$platformUri' doesn't exist";
+ }
if (filename == null) {
throw "Need file to operate on";
}
File file = new File(filename);
if (!file.existsSync()) throw "File $filename doesn't exist.";
+ mainUri = file.absolute.uri;
- await tryToMinimize(file, nnbd);
+ await tryToMinimize();
}
-Future tryToMinimize(File file, bool nnbd) async {
- Uint8List data;
- try {
- String parsedString = getFileAsStringContent(file, nnbd);
- data = utf8.encode(parsedString);
- } catch (e) {
- // If this crash it's a crash in the scanner/parser. It's good to minimize
- // that too.
- data = file.readAsBytesSync();
- }
-
- print("Got data");
-
- Uri main = base.resolve("main.dart");
-
- CompilerContext compilerContext = setupCompilerContext(main);
- Component initialComponent = await getInitialComponent(compilerContext);
- MemoryFileSystem fs = compilerContext.options.fileSystem;
-
+Future tryToMinimize() async {
+ // Set main to be basically empty up front.
+ fs.data[mainUri] = utf8.encode("main() {}");
+ Component initialComponent = await getInitialComponent();
print("Compiled initially (without data)");
+ // Remove fake cache.
+ fs.data.remove(mainUri);
// First assure it actually crash on the input.
- if (!await crashesOnCompile(
- fs, main, data, compilerContext, initialComponent)) {
- throw "Input doesn't crash the compiler: ${dataToText(data)}";
+ if (!await crashesOnCompile(initialComponent)) {
+ throw "Input doesn't crash the compiler.";
}
print("Step #1: We did crash on the input!");
- // Try to delete lines.
- Uint8List latestCrashData =
- await deleteLines(data, fs, main, compilerContext, initialComponent);
- print("We're now at ${latestCrashData.length} bytes.");
+ // All file should now be cached.
+ fs._redirectAndRecord = false;
- // Now try to delete 'arbitrarily' (for any given start offset do an
- // exponential binary search).
- int prevLength = latestCrashData.length;
- while (true) {
- latestCrashData = await binarySearchDeleteData(
- latestCrashData, fs, main, compilerContext, initialComponent);
-
- if (latestCrashData.length == prevLength) {
- // No progress.
- break;
+ // For all dart files: Parse them as set their source as the parsed source
+ // to "get around" any encoding issues when printing later.
+ Map<Uri, Uint8List> copy = new Map.from(fs.data);
+ for (Uri uri in fs.data.keys) {
+ String uriString = uri.toString();
+ if (uriString.endsWith(".json") ||
+ uriString.endsWith(".json") ||
+ uriString.endsWith(".packages") ||
+ uriString.endsWith(".dill") ||
+ fs.data[uri] == null ||
+ fs.data[uri].isEmpty) {
+ // skip
} else {
- print("We're now at ${latestCrashData.length} bytes");
- prevLength = latestCrashData.length;
+ try {
+ String parsedString = getFileAsStringContent(fs.data[uri], nnbd);
+ fs.data[uri] = utf8.encode(parsedString);
+ } catch (e) {
+ // crash in scanner/parser --- keep original file. This crash might
+ // be what we're looking for!
+ }
+ }
+ }
+ if (!await crashesOnCompile(initialComponent)) {
+ // Now - for whatever reason - we didn't crash. Restore.
+ fs.data.clear();
+ fs.data.addAll(copy);
+ }
+
+ // Operate on one file at a time: Try to delete all content in file.
+ List<Uri> uris = new List<Uri>.from(fs.data.keys);
+
+ bool removedSome = true;
+ while (removedSome) {
+ while (removedSome) {
+ removedSome = false;
+ for (int i = 0; i < uris.length; i++) {
+ Uri uri = uris[i];
+ if (fs.data[uri] == null || fs.data[uri].isEmpty) continue;
+ print("About to work on file $i of ${uris.length}");
+ await deleteContent(uris, i, false, initialComponent);
+ if (fs.data[uri] == null || fs.data[uri].isEmpty) removedSome = true;
+ }
+ }
+ int left = 0;
+ for (Uri uri in uris) {
+ if (fs.data[uri] == null || fs.data[uri].isEmpty) continue;
+ left++;
+ }
+ print("There's now $left files of ${fs.data.length} files left");
+
+ // Operate on one file at a time.
+ for (Uri uri in fs.data.keys) {
+ if (fs.data[uri] == null || fs.data[uri].isEmpty) continue;
+
+ print("Now working on $uri");
+
+ // Try to delete lines.
+ int prevLength = fs.data[uri].length;
+ await deleteLines(uri, initialComponent);
+ print("We're now at ${fs.data[uri].length} bytes for $uri.");
+ if (prevLength != fs.data[uri].length) removedSome = true;
+ if (fs.data[uri].isEmpty) continue;
+
+ if (byteDelete) {
+ // Now try to delete 'arbitrarily' (for any given start offset do an
+ // exponential binary search).
+ int prevLength = fs.data[uri].length;
+ while (true) {
+ await binarySearchDeleteData(uri, initialComponent);
+
+ if (fs.data[uri].length == prevLength) {
+ // No progress.
+ break;
+ } else {
+ print("We're now at ${fs.data[uri].length} bytes");
+ prevLength = fs.data[uri].length;
+ removedSome = true;
+ }
+ }
+ }
}
}
- print("Got it down to ${latestCrashData.length} bytes: "
- "${dataToText(latestCrashData)}");
- try {
- String utfDecoded = utf8.decode(latestCrashData, allowMalformed: true);
- print("That's '$utfDecoded' as text");
- } catch (e) {
- print("(which crashes when trying to decode as utf8)");
+ print("\n\nDONE\n\n");
+
+ for (Uri uri in uris) {
+ if (fs.data[uri] == null || fs.data[uri].isEmpty) continue;
+ print("Uri $uri has this content:");
+
+ try {
+ String utfDecoded = utf8.decode(fs.data[uri], allowMalformed: true);
+ print(utfDecoded);
+ } catch (e) {
+ print(fs.data[uri]);
+ print("(which crashes when trying to decode as utf8)");
+ }
+ print("\n\n====================\n\n");
}
}
@@ -152,12 +243,8 @@
return sb.toString();
}
-Future<Uint8List> binarySearchDeleteData(
- Uint8List latestCrashData,
- MemoryFileSystem fs,
- Uri main,
- CompilerContext compilerContext,
- Component initialComponent) async {
+void binarySearchDeleteData(Uri uri, Component initialComponent) async {
+ Uint8List latestCrashData = fs.data[uri];
int offset = 0;
while (offset < latestCrashData.length) {
print("Working at offset $offset of ${latestCrashData.length}");
@@ -165,8 +252,8 @@
builder.add(sublist(latestCrashData, 0, offset));
builder.add(sublist(latestCrashData, offset + 1, latestCrashData.length));
Uint8List candidate = builder.takeBytes();
- if (!await crashesOnCompile(
- fs, main, candidate, compilerContext, initialComponent)) {
+ fs.data[uri] = candidate;
+ if (!await crashesOnCompile(initialComponent)) {
// Deleting 1 char didn't crash; don't try to delete anymore starting
// here.
offset++;
@@ -186,8 +273,8 @@
builder.add(sublist(
latestCrashData, offset + deleteChars, latestCrashData.length));
candidate = builder.takeBytes();
- if (!await crashesOnCompile(
- fs, main, candidate, compilerContext, initialComponent)) {
+ fs.data[uri] = candidate;
+ if (!await crashesOnCompile(initialComponent)) {
noLongerCrashingAt = deleteChars;
break;
}
@@ -210,8 +297,8 @@
builder
.add(sublist(latestCrashData, offset + mid, latestCrashData.length));
candidate = builder.takeBytes();
- if (await crashesOnCompile(
- fs, main, candidate, compilerContext, initialComponent)) {
+ fs.data[uri] = candidate;
+ if (await crashesOnCompile(initialComponent)) {
crashingAt = mid;
} else {
// [noLongerCrashingAt] might actually crash now.
@@ -225,20 +312,81 @@
builder.add(
sublist(latestCrashData, offset + crashingAt, latestCrashData.length));
candidate = builder.takeBytes();
- if (!await crashesOnCompile(
- fs, main, candidate, compilerContext, initialComponent)) {
+ fs.data[uri] = candidate;
+ if (!await crashesOnCompile(initialComponent)) {
throw "Error in binary search.";
}
latestCrashData = candidate;
}
- return latestCrashData;
+
+ fs.data[uri] = latestCrashData;
}
-Future<Uint8List> deleteLines(Uint8List data, MemoryFileSystem fs, Uri main,
- CompilerContext compilerContext, Component initialComponent) async {
+void _tryToRemoveUnreferencedFileContent(Component initialComponent) async {
+ // Check if there now are any unused files.
+ if (_latestComponent == null) return;
+ Set<Uri> neededUris = _latestComponent.uriToSource.keys.toSet();
+ Map<Uri, Uint8List> copy = new Map.from(fs.data);
+ bool removedSome = false;
+ for (MapEntry<Uri, Uint8List> entry in fs.data.entries) {
+ if (entry.value == null || entry.value.isEmpty) continue;
+ if (!entry.key.toString().endsWith(".dart")) continue;
+ if (!neededUris.contains(entry.key)) {
+ fs.data[entry.key] = new Uint8List(0);
+ print(" => Can probably also delete ${entry.key}");
+ removedSome = true;
+ }
+ }
+ if (removedSome) {
+ if (await crashesOnCompile(initialComponent)) {
+ print(" => Yes; Could remove those too!");
+ } else {
+ print(" => No; Couldn't remove those too!");
+ fs.data.clear();
+ fs.data.addAll(copy);
+ }
+ }
+}
+
+void deleteContent(List<Uri> uris, int uriIndex, bool limitTo1,
+ Component initialComponent) async {
+ if (!limitTo1) {
+ Map<Uri, Uint8List> copy = new Map.from(fs.data);
+ // Try to remove content of i and the next 9 (10 files in total).
+ for (int j = uriIndex; j < uriIndex + 10 && j < uris.length; j++) {
+ Uri uri = uris[j];
+ fs.data[uri] = new Uint8List(0);
+ }
+ if (!await crashesOnCompile(initialComponent)) {
+ // Couldn't delete all 10 files. Restore and try the single one.
+ fs.data.clear();
+ fs.data.addAll(copy);
+ } else {
+ for (int j = uriIndex; j < uriIndex + 10 && j < uris.length; j++) {
+ Uri uri = uris[j];
+ print("Can delete all content of file $uri");
+ }
+ await _tryToRemoveUnreferencedFileContent(initialComponent);
+ return;
+ }
+ }
+
+ Uri uri = uris[uriIndex];
+ Uint8List data = fs.data[uri];
+ fs.data[uri] = new Uint8List(0);
+ if (!await crashesOnCompile(initialComponent)) {
+ print("Can't delete all content of file $uri -- keeping it (for now)");
+ fs.data[uri] = data;
+ } else {
+ print("Can delete all content of file $uri");
+ await _tryToRemoveUnreferencedFileContent(initialComponent);
+ }
+}
+
+void deleteLines(Uri uri, Component initialComponent) async {
// Try to delete "lines".
+ Uint8List data = fs.data[uri];
const int $LF = 10;
- Uint8List latestCrashData = data;
List<Uint8List> lines = [];
int start = 0;
for (int i = 0; i < data.length; i++) {
@@ -249,8 +397,16 @@
}
lines.add(sublist(data, start, data.length));
List<bool> include = new List.filled(lines.length, true);
- for (int i = 0; i < lines.length; i++) {
- include[i] = false;
+ Uint8List latestCrashData = data;
+ int length = 1;
+ int i = 0;
+ while (i < lines.length) {
+ if (i + length > lines.length) {
+ length = lines.length - i;
+ }
+ for (int j = i; j < i + length; j++) {
+ include[j] = false;
+ }
final BytesBuilder builder = new BytesBuilder();
for (int j = 0; j < lines.length; j++) {
if (include[j]) {
@@ -261,61 +417,118 @@
}
}
Uint8List candidate = builder.takeBytes();
- if (!await crashesOnCompile(
- fs, main, candidate, compilerContext, initialComponent)) {
- // Didn't crash => Can't remove line i.
- include[i] = true;
+ fs.data[uri] = candidate;
+ if (!await crashesOnCompile(initialComponent)) {
+ // Didn't crash => Can't remove line i-j.
+ for (int j = i; j < i + length; j++) {
+ include[j] = true;
+ }
+ if (length > 2) {
+ // Retry with length 2 at same i.
+ // The idea here is that for instance formatted json might have lines
+ // looking like
+ // {
+ // }
+ // where deleting just one line makes it invalid.
+ length = 2;
+ } else if (length > 1) {
+ // Retry with length 1 at same i.
+ length = 1;
+ } else {
+ // Couldn't with length 1 either.
+ i++;
+ }
} else {
- print("Can delete line $i");
+ print("Can delete line $i (inclusive) - ${i + length} (exclusive) "
+ "(of ${lines.length})");
latestCrashData = candidate;
+ i += length;
+ length *= 2;
}
}
- return latestCrashData;
+ fs.data[uri] = latestCrashData;
}
-Future<bool> crashesOnCompile(MemoryFileSystem fs, Uri main, Uint8List data,
- CompilerContext compilerContext, Component initialComponent) async {
- fs.entityForUri(main).writeAsBytesSync(data);
+Component _latestComponent;
+
+Future<bool> crashesOnCompile(Component initialComponent) async {
IncrementalCompiler incrementalCompiler =
- new IncrementalCompiler.fromComponent(compilerContext, initialComponent);
- incrementalCompiler.invalidate(main);
+ new IncrementalCompiler.fromComponent(
+ setupCompilerContext(), initialComponent);
+ incrementalCompiler.invalidate(mainUri);
try {
- await incrementalCompiler.computeDelta();
+ _latestComponent = await incrementalCompiler.computeDelta();
+ for (Uri uri in invalidate) {
+ incrementalCompiler.invalidate(uri);
+ await incrementalCompiler.computeDelta();
+ }
return false;
- } catch (e) {
- return true;
+ } catch (e, st) {
+ // Find line with #0 in it.
+ String eWithSt = "$e\n\n$st";
+ List<String> lines = eWithSt.split("\n");
+ String foundLine;
+ for (String line in lines) {
+ if (line.startsWith("#0")) {
+ foundLine = line;
+ break;
+ }
+ }
+ if (foundLine == null) throw "Unexpected crash without stacktrace: $e";
+ if (expectedCrashLine == null) {
+ print("Got $foundLine");
+ expectedCrashLine = foundLine;
+ return true;
+ } else if (foundLine == expectedCrashLine) {
+ return true;
+ } else {
+ print("Crashed, but another place: $foundLine");
+ return false;
+ }
}
}
-Future<Component> getInitialComponent(CompilerContext compilerContext) async {
+Future<Component> getInitialComponent() async {
IncrementalCompiler incrementalCompiler =
- new IncrementalCompiler(compilerContext);
+ new IncrementalCompiler(setupCompilerContext());
Component originalComponent = await incrementalCompiler.computeDelta();
return originalComponent;
}
-CompilerContext setupCompilerContext(Uri main) {
- Uint8List sdkSummaryData = new File.fromUri(platformUri).readAsBytesSync();
- MemoryFileSystem fs = new MemoryFileSystem(base);
+CompilerContext setupCompilerContext() {
CompilerOptions options = getOptions();
+ TargetFlags targetFlags = new TargetFlags(
+ enableNullSafety: nnbd, trackWidgetCreation: widgetTransformation);
+ Target target;
+ switch (targetString) {
+ case "VM":
+ target = new VmTarget(targetFlags);
+ break;
+ case "flutter":
+ target = new FlutterTarget(targetFlags);
+ break;
+ case "ddc":
+ target = new DevCompilerTarget(targetFlags);
+ break;
+ default:
+ throw "Unknown target '$target'";
+ }
+ options.target = target;
options.fileSystem = fs;
options.sdkRoot = null;
- options.sdkSummary = sdkSummary;
+ options.sdkSummary = platformUri;
options.omitPlatform = false;
options.onDiagnostic = (DiagnosticMessage message) {
// don't care.
};
- fs.entityForUri(sdkSummary).writeAsBytesSync(sdkSummaryData);
- fs.entityForUri(main).writeAsStringSync("main() {}");
CompilerContext compilerContext = new CompilerContext(
- new ProcessedOptions(options: options, inputs: [main]));
+ new ProcessedOptions(options: options, inputs: [mainUri]));
return compilerContext;
}
-String getFileAsStringContent(File file, bool nnbd) {
- Uint8List rawBytes = file.readAsBytesSync();
+String getFileAsStringContent(Uint8List rawBytes, bool nnbd) {
List<int> lineStarts = new List<int>();
Token firstToken = parser_suite.scanRawBytes(rawBytes,
@@ -342,3 +555,56 @@
enableTripleShift: true,
enableExtensionMethods: true,
enableNonNullable: false);
+
+class FakeFileSystem extends FileSystem {
+ bool _redirectAndRecord = true;
+ final Map<Uri, Uint8List> data = {};
+
+ @override
+ FileSystemEntity entityForUri(Uri uri) {
+ return new FakeFileSystemEntity(this, uri);
+ }
+}
+
+class FakeFileSystemEntity extends FileSystemEntity {
+ final FakeFileSystem fs;
+ final Uri uri;
+ FakeFileSystemEntity(this.fs, this.uri);
+
+ void _ensureCachedIfOk() {
+ if (fs.data.containsKey(uri)) return;
+ if (!fs._redirectAndRecord) {
+ throw "Asked for file in non-recording mode that wasn't known";
+ }
+ File f = new File.fromUri(uri);
+ if (!f.existsSync()) {
+ fs.data[uri] = null;
+ return;
+ }
+ fs.data[uri] = f.readAsBytesSync();
+ }
+
+ @override
+ Future<bool> exists() {
+ _ensureCachedIfOk();
+ Uint8List data = fs.data[uri];
+ if (data == null) return Future.value(false);
+ return Future.value(true);
+ }
+
+ @override
+ Future<List<int>> readAsBytes() {
+ _ensureCachedIfOk();
+ Uint8List data = fs.data[uri];
+ if (data == null) throw new FileSystemException(uri, "File doesn't exist.");
+ return Future.value(data);
+ }
+
+ @override
+ Future<String> readAsString() {
+ _ensureCachedIfOk();
+ Uint8List data = fs.data[uri];
+ if (data == null) throw new FileSystemException(uri, "File doesn't exist.");
+ return Future.value(utf8.decode(data));
+ }
+}
diff --git a/pkg/front_end/test/fasta/textual_outline_suite.dart b/pkg/front_end/test/fasta/textual_outline_suite.dart
new file mode 100644
index 0000000..fa98bdb
--- /dev/null
+++ b/pkg/front_end/test/fasta/textual_outline_suite.dart
@@ -0,0 +1,117 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE.md file.
+
+library fasta.test.textual_outline_test;
+
+import 'dart:async' show Future;
+import 'dart:io';
+
+import 'package:dart_style/dart_style.dart' show DartFormatter;
+
+import 'package:front_end/src/fasta/util/textual_outline.dart';
+import 'package:testing/testing.dart'
+ show
+ Chain,
+ ChainContext,
+ Expectation,
+ ExpectationSet,
+ Result,
+ Step,
+ TestDescription,
+ runMe;
+
+import '../utils/kernel_chain.dart' show MatchContext;
+
+const List<Map<String, String>> EXPECTATIONS = [
+ {
+ "name": "ExpectationFileMismatch",
+ "group": "Fail",
+ },
+ {
+ "name": "ExpectationFileMissing",
+ "group": "Fail",
+ },
+ {
+ "name": "EmptyOutput",
+ "group": "Fail",
+ },
+ {
+ "name": "FormatterCrash",
+ "group": "Fail",
+ },
+];
+
+Future<Context> createContext(
+ Chain suite, Map<String, String> environment) async {
+ return new Context(environment["updateExpectations"] == "true");
+}
+
+main([List<String> arguments = const []]) =>
+ runMe(arguments, createContext, configurationPath: "../../testing.json");
+
+class Context extends ChainContext with MatchContext {
+ final bool updateExpectations;
+ Context(this.updateExpectations);
+
+ final List<Step> steps = const <Step>[
+ const TextualOutline(),
+ ];
+
+ final ExpectationSet expectationSet =
+ new ExpectationSet.fromJsonList(EXPECTATIONS);
+}
+
+class TextualOutline extends Step<TestDescription, TestDescription, Context> {
+ const TextualOutline();
+
+ String get name => "TextualOutline";
+
+ Future<Result<TestDescription>> run(
+ TestDescription description, Context context) async {
+ List<int> bytes = new File.fromUri(description.uri).readAsBytesSync();
+ for (bool modelled in [false, true]) {
+ String result = textualOutline(bytes,
+ throwOnUnexpected: true, performModelling: modelled);
+ if (result == null) {
+ return new Result(null, context.expectationSet["EmptyOutput"],
+ description.uri, StackTrace.current);
+ }
+
+ // In an attempt to make it less sensitive to formatting first remove
+ // excess new lines, then format.
+ List<String> lines = result.split("\n");
+ StringBuffer sb = new StringBuffer();
+ for (String line in lines) {
+ if (line.trim() != "") sb.writeln(line);
+ }
+ result = sb.toString().trim();
+
+ // Try to format.
+ Exception formatterException;
+ StackTrace formatterExceptionSt;
+ try {
+ result = new DartFormatter().format(result);
+ } catch (e, st) {
+ formatterException = e;
+ formatterExceptionSt = st;
+ }
+
+ String filename = ".textual_outline.expect";
+ if (modelled) {
+ filename = ".textual_outline_modelled.expect";
+ }
+
+ Result expectMatch = await context.match<TestDescription>(
+ filename, result, description.uri, description);
+ if (expectMatch.outcome != Expectation.Pass) return expectMatch;
+
+ if (formatterException != null) {
+ return new Result(null, context.expectationSet["FormatterCrash"],
+ formatterException, formatterExceptionSt);
+ }
+ }
+
+ return new Result.pass(description);
+ }
+}
diff --git a/pkg/front_end/test/parser_test_listener.dart b/pkg/front_end/test/parser_test_listener.dart
index 144ea05..54b7c6b 100644
--- a/pkg/front_end/test/parser_test_listener.dart
+++ b/pkg/front_end/test/parser_test_listener.dart
@@ -265,15 +265,15 @@
}
void endExtensionDeclaration(
- Token extensionKeyword, Token onKeyword, Token token) {
+ Token extensionKeyword, Token onKeyword, Token endToken) {
indent--;
seen(extensionKeyword);
seen(onKeyword);
- seen(token);
+ seen(endToken);
doPrint('endExtensionDeclaration('
'$extensionKeyword, '
'$onKeyword, '
- '$token)');
+ '$endToken)');
}
void beginCombinators(Token token) {
diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt
index 5d57d7835..d342281 100644
--- a/pkg/front_end/test/spell_checking_list_code.txt
+++ b/pkg/front_end/test/spell_checking_list_code.txt
@@ -43,6 +43,7 @@
ap
api
app
+apparently
applicable
arg
args
@@ -154,6 +155,7 @@
charcode
chars
checkpoint
+chunks
ci
ck
cl
@@ -578,6 +580,7 @@
lm
locationd
logging
+logically
lots
lp
lparen
@@ -605,6 +608,7 @@
me
merely
meta
+metadata's
method10a
method10b
method1a
@@ -640,6 +644,7 @@
mm
mn
mockito
+modelling
momentarily
monomorphic
morebottom
@@ -714,6 +719,7 @@
orphans
ors
os
+outputting
overlap
overloader
overshadowed
@@ -895,6 +901,7 @@
rooted
roughly
rounding
+roundtrip
rparen
rpc
rs
@@ -959,6 +966,7 @@
sole
solely
somewhat
+sortable
sourcemap
spaced
sparse
@@ -985,6 +993,7 @@
stdout
stmt
str
+streak
streaming
strict
stringified
@@ -1051,6 +1060,7 @@
testers
testing
tex
+textualize
tflite
th
therein
diff --git a/pkg/front_end/test/spell_checking_list_tests.txt b/pkg/front_end/test/spell_checking_list_tests.txt
index 2b8ccc0..2c2610c 100644
--- a/pkg/front_end/test/spell_checking_list_tests.txt
+++ b/pkg/front_end/test/spell_checking_list_tests.txt
@@ -179,6 +179,7 @@
err
everytime
evicting
+excess
exe
execute
exercised
@@ -351,6 +352,7 @@
misspelled
mistake
mistakes
+modelled
month
moo
mx
@@ -449,6 +451,7 @@
sdks
secondary
segment
+sensitive
severe
sheets
shipped
diff --git a/pkg/front_end/test/textual_outline_test.dart b/pkg/front_end/test/textual_outline_test.dart
new file mode 100644
index 0000000..c22aff6
--- /dev/null
+++ b/pkg/front_end/test/textual_outline_test.dart
@@ -0,0 +1,99 @@
+import "dart:convert";
+import "package:front_end/src/fasta/util/textual_outline.dart";
+
+main() {
+ // Doesn't sort if not asked to perform modelling.
+ String result = textualOutline(utf8.encode("""
+b() { print("hello"); }
+a() { print("hello"); }
+"""), throwOnUnexpected: true, performModelling: false);
+ if (result !=
+ """
+b() { }
+
+a() { }""") {
+ throw "Unexpected result: $result";
+ }
+
+ // Sort if asked to perform modelling.
+ result = textualOutline(utf8.encode("""
+b() { print("hello"); }
+a() { print("hello"); }
+"""), throwOnUnexpected: true, performModelling: true);
+ if (result !=
+ """
+a() { }
+
+b() { }""") {
+ throw "Unexpected result: $result";
+ }
+
+ // Content between braces or not doesn't make any difference.
+ // Procedure without content.
+ result = textualOutline(utf8.encode("""
+a() {}
+"""), throwOnUnexpected: true, performModelling: true);
+ if (result !=
+ """
+a() { }""") {
+ throw "Unexpected result: $result";
+ }
+
+ // Procedure with content.
+ result = textualOutline(utf8.encode("""
+a() {
+ // Whatever
+}
+"""), throwOnUnexpected: true, performModelling: true);
+ if (result !=
+ """
+a() { }""") {
+ throw "Unexpected result: $result";
+ }
+
+ // Class without content.
+ result = textualOutline(utf8.encode("""
+class A {}
+"""), throwOnUnexpected: true, performModelling: true);
+ if (result !=
+ """
+class A {
+}""") {
+ throw "Unexpected result: $result";
+ }
+
+ // Class without real content.
+ result = textualOutline(utf8.encode("""
+class A {
+ // Whatever
+}
+"""), throwOnUnexpected: true, performModelling: true);
+ if (result !=
+ """
+class A {
+}""") {
+ throw "Unexpected result: $result";
+ }
+
+ // Has space between entries.
+ result = textualOutline(utf8.encode("""
+@a
+@A(2)
+typedef void F1();
+
+@a
+@A(3)
+int f1, f2;
+"""), throwOnUnexpected: true, performModelling: true);
+ if (result !=
+ """
+@a
+@A(2)
+typedef void F1();
+
+@a
+@A(3)
+int f1, f2;""") {
+ throw "Unexpected result: $result";
+ }
+}
diff --git a/pkg/front_end/test/utils/kernel_chain.dart b/pkg/front_end/test/utils/kernel_chain.dart
index 855e343..01edfe0 100644
--- a/pkg/front_end/test/utils/kernel_chain.dart
+++ b/pkg/front_end/test/utils/kernel_chain.dart
@@ -50,6 +50,7 @@
import 'package:kernel/text/text_serialization_verifier.dart'
show
+ RoundTripStatus,
TextDeserializationFailure,
TextRoundTripFailure,
TextSerializationFailure,
@@ -345,6 +346,12 @@
class KernelTextSerialization
extends Step<ComponentResult, ComponentResult, ChainContext> {
+ static const bool writeRoundTripStatus = bool.fromEnvironment(
+ "text_serialization.writeRoundTripStatus",
+ defaultValue: false);
+
+ static const String suffix = ".roundtrip";
+
const KernelTextSerialization();
String get name => "kernel text serialization";
@@ -402,6 +409,20 @@
options.report(message, message.code.severity);
}
+ if (writeRoundTripStatus) {
+ Uri uri = component.uriToSource.keys
+ .firstWhere((uri) => uri?.scheme == "file");
+ String filename = "${uri.toFilePath()}${suffix}";
+ uri = new File(filename).uri;
+ StringBuffer buffer = new StringBuffer();
+ for (RoundTripStatus status in verifier.status) {
+ status.printOn(buffer);
+ }
+ await openWrite(uri, (IOSink sink) {
+ sink.write(buffer.toString());
+ });
+ }
+
if (verifier.failures.isNotEmpty) {
return new Result<ComponentResult>(
null,
diff --git a/pkg/front_end/testcases/agnostic/identical.dart.textual_outline.expect b/pkg/front_end/testcases/agnostic/identical.dart.textual_outline.expect
new file mode 100644
index 0000000..a880d41
--- /dev/null
+++ b/pkg/front_end/testcases/agnostic/identical.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+const a = <int>[];
+const b = <int?>[];
+const c = identical(a, b);
+main() {}
diff --git a/pkg/front_end/testcases/agnostic/identical.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/agnostic/identical.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a880d41
--- /dev/null
+++ b/pkg/front_end/testcases/agnostic/identical.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+const a = <int>[];
+const b = <int?>[];
+const c = identical(a, b);
+main() {}
diff --git a/pkg/front_end/testcases/agnostic/map.dart.textual_outline.expect b/pkg/front_end/testcases/agnostic/map.dart.textual_outline.expect
new file mode 100644
index 0000000..afb6162
--- /dev/null
+++ b/pkg/front_end/testcases/agnostic/map.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+const a = <int>[];
+const b = <int?>[];
+const c = {a: 0, b: 1};
+main() {}
diff --git a/pkg/front_end/testcases/agnostic/map.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/agnostic/map.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..afb6162
--- /dev/null
+++ b/pkg/front_end/testcases/agnostic/map.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+const a = <int>[];
+const b = <int?>[];
+const c = {a: 0, b: 1};
+main() {}
diff --git a/pkg/front_end/testcases/agnostic/set.dart.textual_outline.expect b/pkg/front_end/testcases/agnostic/set.dart.textual_outline.expect
new file mode 100644
index 0000000..5de47e7
--- /dev/null
+++ b/pkg/front_end/testcases/agnostic/set.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+const a = <int>[];
+const b = <int?>[];
+const c = {a, b};
+main() {}
diff --git a/pkg/front_end/testcases/agnostic/set.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/agnostic/set.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5de47e7
--- /dev/null
+++ b/pkg/front_end/testcases/agnostic/set.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+const a = <int>[];
+const b = <int?>[];
+const c = {a, b};
+main() {}
diff --git a/pkg/front_end/testcases/extensions/ambiguous.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/ambiguous.dart.textual_outline.expect
new file mode 100644
index 0000000..b00cda9
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/ambiguous.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+extension A ;
+on C (){ }
+extension B ;
+on C (){ }
+class C {
+}
+errors(C c) { }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/annotations.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/annotations.dart.textual_outline.expect
new file mode 100644
index 0000000..2140404
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/annotations.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class Class {
+ @pragma('dart2js:noInline')
+ instanceMethod() { }
+ @pragma('dart2js:noInline')
+ static staticMethod() { }
+}
+extension Extension ;
+on Class (){ }
+@pragma('dart2js:noInline')
+topLevelMethod() { }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/builtin_identifiers.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/builtin_identifiers.dart.textual_outline.expect
new file mode 100644
index 0000000..05b0d78
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/builtin_identifiers.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+extension ;
+mixin on int {
+}
+extension extension ;
+on int (){ }
+extension as ;
+on int (){ }
+void main() { }
diff --git a/pkg/front_end/testcases/extensions/call_methods.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/call_methods.dart.textual_outline.expect
new file mode 100644
index 0000000..3caae41
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/call_methods.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+class A {
+ String get call => "My name is A";
+}
+class B {
+ String Function() get call => () => "My name is B";
+}
+extension on ;
+int (){ }
+extension on ;
+num (){ }
+extension on ;
+String (){ }
+main() { }
+var topLevel1 = 1(10);
+var topLevel2 = 1("10");
+var topLevel3 = 1.0(10);
+var topLevel4 = 1.0("10");
+A a = new A();
+var topLevel5 = a(2);
+B b = new B();
+var topLevel6 = a(2, "3");
+errors() { }
diff --git a/pkg/front_end/testcases/extensions/check_bounds.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/check_bounds.dart.textual_outline.expect
new file mode 100644
index 0000000..5d1e2be
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/check_bounds.dart.textual_outline.expect
@@ -0,0 +1,43 @@
+part 'check_bounds_lib.dart';
+class A {
+}
+class B extends A {
+}
+class Class<T extends A> {
+}
+extension Extension<T extends B> ( ){ }
+on Class<T> (){ }
+main() { }
+test() { }
+final A a = new A();
+final Class<A> classA = new Class<A>();
+final field1 = classA.method();
+final field2 = Extension(classA).method();
+final field3 = Extension<A>(classA).method();
+final field4 = Extension<B>(classA).method();
+final field5 = Extension(classA).genericMethod(a);
+final field6 = Extension(classA).genericMethod<A>(a);
+final field7 = Extension(classA).genericMethod<B>(a);
+final field8 = Extension<A>(classA).genericMethod(a);
+final field9 = Extension<A>(classA).genericMethod<A>(a);
+final field10 = Extension<A>(classA).genericMethod<B>(a);
+final field11 = Extension<B>(classA).genericMethod(a);
+final field12 = Extension<B>(classA).genericMethod<A>(a);
+final field13 = Extension<B>(classA).genericMethod<B>(a);
+final Class<B> classB = new Class<B>();
+final field14 = classB.method();
+final field15 = Extension(classB).method();
+final field16 = Extension<A>(classB).method();
+final field17 = Extension<B>(classB).method();
+final field18 = classB.genericMethod(a);
+final field19 = classB.genericMethod<A>(a);
+final field20 = classB.genericMethod<B>(a);
+final field21 = Extension(classB).genericMethod(a);
+final field22 = Extension(classB).genericMethod<A>(a);
+final field23 = Extension(classB).genericMethod<B>(a);
+final field24 = Extension<A>(classB).genericMethod(a);
+final field25 = Extension<A>(classB).genericMethod<A>(a);
+final field26 = Extension<A>(classB).genericMethod<B>(a);
+final field27 = Extension<B>(classB).genericMethod(a);
+final field28 = Extension<B>(classB).genericMethod<A>(a);
+final field29 = Extension<B>(classB).genericMethod<B>(a);
diff --git a/pkg/front_end/testcases/extensions/compounds.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/compounds.dart.textual_outline.expect
new file mode 100644
index 0000000..38afdf4
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/compounds.dart.textual_outline.expect
@@ -0,0 +1,30 @@
+class Number {
+ final int value;
+ Number(this.value);
+ int get hashCode => value.hashCode;
+ bool operator ==(Object other) => other is Number && value == other.value;
+ String toString() => 'Number($value)';
+}
+extension NumberExtension ;
+on Number (){ }
+class Class {
+ Number field;
+ Class(this.field);
+}
+extension ClassExtension ;
+on Class (){ }
+class IntClass {
+ int field;
+ IntClass(this.field);
+}
+extension IntClassExtension ;
+on IntClass (){ }
+main() { }
+testLocals() { }
+testProperties() { }
+testIntProperties() { }
+testExplicitProperties() { }
+testExplicitIntProperties() { }
+testExplicitNullAwareProperties(Class v) { }
+testExplicitNullAwareIntProperties(IntClass v) { }
+expect(expected, actual, [expectNull = false]) { }
diff --git a/pkg/front_end/testcases/extensions/conflict_with_object.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/conflict_with_object.dart.textual_outline.expect
new file mode 100644
index 0000000..f358632
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/conflict_with_object.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+extension Extension ;
+on String (){ }
+main() { }
+errors() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/extensions/conflicts.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/conflicts.dart.textual_outline.expect
new file mode 100644
index 0000000..b98a63e
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/conflicts.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+class Class1 {
+}
+class Class2 {
+}
+extension DuplicateExtensionName ;
+on Class1 (){ }
+extension DuplicateExtensionName ;
+on Class2 (){ }
+extension UniqueExtensionName ;
+on Class1 (){ }
+main() { }
+errors() { }
diff --git a/pkg/front_end/testcases/extensions/default_values.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/default_values.dart.textual_outline.expect
new file mode 100644
index 0000000..a5ed09e
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/default_values.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class Class {
+}
+extension Extension ;
+on Class (){ }
+main() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.textual_outline.expect
new file mode 100644
index 0000000..5dedc9b
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'deferred_explicit_access_lib.dart' deferred as prefix;
+
+main() async {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..45edf2b
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'deferred_explicit_access_lib.dart' deferred as prefix;
+
+expect(expected, actual) {}
+main() async {}
diff --git a/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.textual_outline.expect
new file mode 100644
index 0000000..cd5075c
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'deferred_explicit_access_lib.dart' deferred as prefix hide Extension;
+
+main() async {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..73bcfb8
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'deferred_explicit_access_lib.dart' deferred as prefix hide Extension;
+
+expect(expected, actual) {}
+main() async {}
diff --git a/pkg/front_end/testcases/extensions/direct_instance_access.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/direct_instance_access.dart.textual_outline.expect
new file mode 100644
index 0000000..0b176c5
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/direct_instance_access.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class Class {
+ var field;
+}
+extension Extension ;
+on Class (){ }
+class GenericClass<T> {
+ T field;
+}
+extension GenericExtension<T> ( ){ }
+on GenericClass<T> (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/direct_static_access.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/direct_static_access.dart.textual_outline.expect
new file mode 100644
index 0000000..e29ee8a
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/direct_static_access.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class Class<T> {
+ static var field;
+}
+extension Extension<T> ( ){ }
+on Class<T> (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/dynamic_invoke.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/dynamic_invoke.dart.textual_outline.expect
new file mode 100644
index 0000000..55962d9
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/dynamic_invoke.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class Class {
+ noSuchMethod(Invocation i) => 123;
+}
+extension ClassExtension ;
+on Class (){ }
+extension Extension ;
+on dynamic (){ }
+main() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/extensions/explicit_extension_access.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/explicit_extension_access.dart.textual_outline.expect
new file mode 100644
index 0000000..2a52c91
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/explicit_extension_access.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class Class {
+ int field1 = 42;
+ int field2 = 87;
+}
+extension Extension1 ;
+on Class (){ }
+extension Extension2 ;
+on Class (){ }
+main() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/extensions/explicit_extension_inference.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/explicit_extension_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..2fbeb56
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/explicit_extension_inference.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class A {
+}
+class B extends A {
+}
+class C extends B {
+}
+class GenericClass<T> {
+}
+extension GenericExtension<T> ( ){ }
+on GenericClass<T> (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/explicit_generic_extension_access.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/explicit_generic_extension_access.dart.textual_outline.expect
new file mode 100644
index 0000000..58b2995
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/explicit_generic_extension_access.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class Class<T extends num> {
+ T field1;
+ T field2;
+ Class(this.field1, this.field2);
+}
+extension Extension1<T extends num> ( ){ }
+on Class<T> (){ }
+extension Extension2<T extends num> ( ){ }
+on Class<T> (){ }
+main() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/extensions/explicit_invalid_access.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/explicit_invalid_access.dart.textual_outline.expect
new file mode 100644
index 0000000..3cf71b3
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/explicit_invalid_access.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class Class {
+}
+extension Extension ;
+on Class (){ }
+errors(Class c) { }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/explicit_this.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/explicit_this.dart.textual_outline.expect
new file mode 100644
index 0000000..7311a2f
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/explicit_this.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class A1 {
+ Object field;
+ void method1() { }
+}
+extension A2 ;
+on A1 (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/export_twice.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/export_twice.dart.textual_outline.expect
new file mode 100644
index 0000000..3e4ce72
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/export_twice.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'export_twice_lib1.dart';
+import 'export_twice_lib2.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/export_twice.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/export_twice.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3e4ce72
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/export_twice.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'export_twice_lib1.dart';
+import 'export_twice_lib2.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/extension_call.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/extension_call.dart.textual_outline.expect
new file mode 100644
index 0000000..aea56da
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/extension_call.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class Class<T> {
+ T method(T a) => a;
+}
+extension Extension<T> ( ){ }
+on Class<T> (){ }
+main() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/extensions/extension_constructor.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/extension_constructor.dart.textual_outline.expect
new file mode 100644
index 0000000..65b9864
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/extension_constructor.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class Class {
+}
+extension Extension ;
+on Class (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/extension_field_with_type_parameter_usage.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/extension_field_with_type_parameter_usage.dart.textual_outline.expect
new file mode 100644
index 0000000..4f88b19
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/extension_field_with_type_parameter_usage.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+extension E<U> ( ){ }
+on String (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/extension_methods.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/extension_methods.dart.textual_outline.expect
new file mode 100644
index 0000000..98012b9
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/extension_methods.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+import 'package:expect/expect.dart';
+class C {
+ int get one => 1;
+}
+extension E ;
+on C (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/extension_setter.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/extension_setter.dart.textual_outline.expect
new file mode 100644
index 0000000..8c8aedc
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/extension_setter.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class Class {
+ int field;
+}
+extension Extension ;
+on Class (){ }
+class GenericClass<T> {
+}
+extension GenericExtension<T> ( ){ }
+on GenericClass<T> (){ }
+main() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/extensions/extension_setter_error.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/extension_setter_error.dart.textual_outline.expect
new file mode 100644
index 0000000..879feda
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/extension_setter_error.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class GenericClass<T> {
+}
+extension GenericExtension<T> ( ){ }
+on GenericClass<T> (){ }
+error() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/extensions/generic_function_in_generic_extension.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/generic_function_in_generic_extension.dart.textual_outline.expect
new file mode 100644
index 0000000..b85f14c
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/generic_function_in_generic_extension.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class Class<T> {
+}
+extension Extension<T> ( ){ }
+on Class<T> (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/getter_setter_conflict.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/getter_setter_conflict.dart.textual_outline.expect
new file mode 100644
index 0000000..f9708a2
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/getter_setter_conflict.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class Class {
+ int get m1 => 0;
+ void set m2(int x) { }
+}
+extension Extension0 ;
+on Class (){ }
+extension Extension1 ;
+on Class (){ }
+main() { }
+errors() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/extensions/if_null.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/if_null.dart.textual_outline.expect
new file mode 100644
index 0000000..1108949
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/if_null.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class Class {
+ int field;
+}
+extension Extension ;
+on Class (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/implicit_extension_inference.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/implicit_extension_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..2fbeb56
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/implicit_extension_inference.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class A {
+}
+class B extends A {
+}
+class C extends B {
+}
+class GenericClass<T> {
+}
+extension GenericExtension<T> ( ){ }
+on GenericClass<T> (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/implicit_this.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/implicit_this.dart.textual_outline.expect
new file mode 100644
index 0000000..7311a2f
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/implicit_this.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class A1 {
+ Object field;
+ void method1() { }
+}
+extension A2 ;
+on A1 (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/import_via_prefix.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/import_via_prefix.dart.textual_outline.expect
new file mode 100644
index 0000000..b1848ace
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/import_via_prefix.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'import_via_prefix_lib.dart' as prefix;
+
+main() {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/extensions/import_via_prefix.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/import_via_prefix.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..72ac1a4
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/import_via_prefix.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'import_via_prefix_lib.dart' as prefix;
+
+expect(expected, actual) {}
+main() {}
diff --git a/pkg/front_end/testcases/extensions/index.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/index.dart.textual_outline.expect
new file mode 100644
index 0000000..e077e2c
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/index.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+class MapLike<K, V> {
+ final Map<K, V> _map = {};
+ V get(Object key) => _map[key];
+ V put(K key, V value) => _map[key] = value;
+}
+extension Extension<K, V> ( ){ }
+on MapLike<K, V> (){ }
+main() { }
+implicit() { }
+explicitWithTypeArguments() { }
+explicitInferredTypeArguments() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/extensions/instance_access.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/instance_access.dart.textual_outline.expect
new file mode 100644
index 0000000..06c1ade
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/instance_access.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+class Class1 {
+ int field;
+ Class1(this.field);
+ String toString() => 'Class1($field)';
+}
+class Class2 {
+ int field;
+ Class2(this.field);
+ String toString() => 'Class2($field)';
+}
+extension Extension1 ;
+on Class1 (){ }
+extension Extension2 ;
+on Class2 (){ }
+main() { }
+testExtension1() { }
+testExtension2() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/extensions/instance_access_of_static.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/instance_access_of_static.dart.textual_outline.expect
new file mode 100644
index 0000000..d1d5ea8
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/instance_access_of_static.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class Class1 {
+}
+extension Extension1 ;
+on Class1 (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/instance_members.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/instance_members.dart.textual_outline.expect
new file mode 100644
index 0000000..04526ab
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/instance_members.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class A1 {
+}
+extension A2 ;
+on A1 (){ }
+class B1<T> {
+}
+extension B2<T> ( ){ }
+on B1<T> (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/instance_tearoff.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/instance_tearoff.dart.textual_outline.expect
new file mode 100644
index 0000000..06c1ade
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/instance_tearoff.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+class Class1 {
+ int field;
+ Class1(this.field);
+ String toString() => 'Class1($field)';
+}
+class Class2 {
+ int field;
+ Class2(this.field);
+ String toString() => 'Class2($field)';
+}
+extension Extension1 ;
+on Class1 (){ }
+extension Extension2 ;
+on Class2 (){ }
+main() { }
+testExtension1() { }
+testExtension2() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/extensions/internal_resolution.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/internal_resolution.dart.textual_outline.expect
new file mode 100644
index 0000000..ae4f7ac
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/internal_resolution.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class Class {
+ int field;
+}
+extension on ;
+Class (){ }
+extension on ;
+Class (){ }
+main() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.textual_outline.expect
new file mode 100644
index 0000000..e289bf8
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class Class {
+}
+extension Extension ;
+on Class (){ }
+class GenericClass<T> {
+}
+extension GenericExtension<T> ( ){ }
+on GenericClass<T> (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart.textual_outline.expect
new file mode 100644
index 0000000..fc40e6f
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/invalid_explicit_static_access.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+extension Extension ;
+on String (){ }
+main() { }
+errors() { }
diff --git a/pkg/front_end/testcases/extensions/issue38600.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/issue38600.dart.textual_outline.expect
new file mode 100644
index 0000000..166eb7d
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/issue38600.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class Class<T> {
+}
+extension ;
+try<T> ( ){ }
+on Class<T> (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/issue38712.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/issue38712.dart.textual_outline.expect
new file mode 100644
index 0000000..409afa3
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/issue38712.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+extension C (){ }
+void main() { }
diff --git a/pkg/front_end/testcases/extensions/issue38713.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/issue38713.dart.textual_outline.expect
new file mode 100644
index 0000000..8d9d55d
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/issue38713.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+extension C ;
+on int (){ }
+void main() { }
diff --git a/pkg/front_end/testcases/extensions/issue38745.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/issue38745.dart.textual_outline.expect
new file mode 100644
index 0000000..71fe604
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/issue38745.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class C<T> {
+}
+extension ext<T> ( ){ }
+on C<T> (){ }
+main() { }
+errors() { }
diff --git a/pkg/front_end/testcases/extensions/issue38750.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/issue38750.dart.textual_outline.expect
new file mode 100644
index 0000000..5bc7316
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/issue38750.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'issue38750_lib1.dart';
+import 'issue38750_lib2.dart';
+
+main() {}
+errors() {}
diff --git a/pkg/front_end/testcases/extensions/issue38750.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/issue38750.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cca0335
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/issue38750.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import 'issue38750_lib1.dart';
+import 'issue38750_lib2.dart';
+
+errors() {}
+main() {}
diff --git a/pkg/front_end/testcases/extensions/issue38755.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/issue38755.dart.textual_outline.expect
new file mode 100644
index 0000000..2b553f1
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/issue38755.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+final list = ["a", "b", "c"].myMap((it) => it);
+extension A<T> ( ){ }
+on List<T> (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/issue38915.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/issue38915.dart.textual_outline.expect
new file mode 100644
index 0000000..65b9864
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/issue38915.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class Class {
+}
+extension Extension ;
+on Class (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/issue39527.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/issue39527.dart.textual_outline.expect
new file mode 100644
index 0000000..816061d
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/issue39527.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class C {
+ int value = 0;
+}
+extension Extension1 ;
+on C (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/issue39889.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/issue39889.dart.textual_outline.expect
new file mode 100644
index 0000000..9225dc9e
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/issue39889.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class C {
+}
+extension E ;
+on C (){ }
+void main() { }
diff --git a/pkg/front_end/testcases/extensions/issue39938/issue39938.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/issue39938/issue39938.dart.textual_outline.expect
new file mode 100644
index 0000000..5a7bb14
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/issue39938/issue39938.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'issue39938_lib.dart';
+
+main() {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/extensions/issue39938/issue39938.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/issue39938/issue39938.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..55e3b57
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/issue39938/issue39938.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'issue39938_lib.dart';
+
+expect(expected, actual) {}
+main() {}
diff --git a/pkg/front_end/testcases/extensions/issue40596.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/issue40596.dart.textual_outline.expect
new file mode 100644
index 0000000..0060108
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/issue40596.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'dart:async';
+void main() { }
+extension Extension<T> ( ){ }
+on Stream<T> (){ }
diff --git a/pkg/front_end/testcases/extensions/issue40713.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/issue40713.dart.textual_outline.expect
new file mode 100644
index 0000000..793db07
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/issue40713.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+extension SafeAccess<T> ( ){ }
+on Iterable<T> (){ }
+main() { }
+void test() { }
+void errors() { }
diff --git a/pkg/front_end/testcases/extensions/issue40816.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/issue40816.dart.textual_outline.expect
new file mode 100644
index 0000000..a6e9b07
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/issue40816.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class A {
+}
+class B {
+}
+extension on ;
+A (){ }
+void main() { }
diff --git a/pkg/front_end/testcases/extensions/missing_toplevel.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/missing_toplevel.dart.textual_outline.expect
new file mode 100644
index 0000000..8e5a18a
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/missing_toplevel.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class Class {
+}
+extension Extension ;
+on Class (){ }
+var c = new Class();
+var missingGetter = c.setter += 42;
+main() { }
diff --git a/pkg/front_end/testcases/extensions/nested_on_types.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/nested_on_types.dart.textual_outline.expect
new file mode 100644
index 0000000..c3bdbbe
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/nested_on_types.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class A<T> {
+}
+extension Extension<T> ( ){ }
+on A<A<T>> (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/null_aware.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/null_aware.dart.textual_outline.expect
new file mode 100644
index 0000000..59bc4b7
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/null_aware.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class Class {
+ int field;
+}
+extension Extension ;
+on Class (){ }
+main() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/extensions/on_function_type.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/on_function_type.dart.textual_outline.expect
new file mode 100644
index 0000000..12d1fac
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/on_function_type.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+extension<R, T> on ;
+R Function(T) { }
+class Class<T extends Class<T>> {
+}
+class Subclass extends Class<Subclass> {
+}
+extension<T extends Class<T>> on ;
+dynamic Function<S extends T>(T, S) { }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/on_type_inference.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/on_type_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..d115666
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/on_type_inference.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+extension BestCom<T extends num> ( ){ }
+on Iterable<T> (){ }
+extension BestList<T> ( ){ }
+on List<T> (){ }
+extension BestSpec ;
+on List<num> (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/on_type_variable_inference.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/on_type_variable_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..bc1e66f
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/on_type_variable_inference.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+class Struct {
+}
+class StructA extends Struct {
+}
+class StructB extends Struct {
+}
+class NonStruct {
+}
+extension Extension<T extends Struct> ( ){ }
+on T (){ }
+main() { }
+testNonStruct() { }
diff --git a/pkg/front_end/testcases/extensions/operators.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/operators.dart.textual_outline.expect
new file mode 100644
index 0000000..b40e2fb
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/operators.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+class Complex {
+ final double real;
+ final double imaginary;
+ const Complex(this.real, this.imaginary);
+ Complex add(Complex other) { }
+ Complex sub(Complex other) { }
+ Complex negate() { }
+ int get hashCode => real.hashCode * 13 + imaginary.hashCode * 19;
+ bool operator ==(Object other) { }
+ String toString() => 'Complex($real,$imaginary)';
+}
+extension Operators ;
+on Complex (){ }
+main() { }
+implicit() { }
+explicit() { }
+void errors(Complex c) { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/extensions/other_kinds.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/other_kinds.dart.textual_outline.expect
new file mode 100644
index 0000000..7fd35bd
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/other_kinds.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class A1 {
+ int _instanceField;
+ int getInstanceField() => _instanceField;
+ void setInstanceField(int value) { }
+ static int _staticField = 0;
+ static int getStaticField() => _staticField;
+ static void setStaticField(int value) { }
+}
+extension A2 ;
+on A1 (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/private_members.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/private_members.dart.textual_outline.expect
new file mode 100644
index 0000000..ca40cab
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/private_members.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'private_members_lib.dart';
+
+main() {}
+errors() {}
diff --git a/pkg/front_end/testcases/extensions/private_members.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/private_members.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..dfeb024
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/private_members.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'private_members_lib.dart';
+
+errors() {}
+main() {}
diff --git a/pkg/front_end/testcases/extensions/static_access.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/static_access.dart.textual_outline.expect
new file mode 100644
index 0000000..65b9864
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/static_access.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class Class {
+}
+extension Extension ;
+on Class (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/static_access_of_instance.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/static_access_of_instance.dart.textual_outline.expect
new file mode 100644
index 0000000..65b9864
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/static_access_of_instance.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class Class {
+}
+extension Extension ;
+on Class (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/tear_offs.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/tear_offs.dart.textual_outline.expect
new file mode 100644
index 0000000..c80f35f
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/tear_offs.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class Class {
+}
+extension Extension ;
+on Class (){ }
+main() { }
+errors() { }
diff --git a/pkg/front_end/testcases/extensions/type_variables.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/type_variables.dart.textual_outline.expect
new file mode 100644
index 0000000..dd1a367
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/type_variables.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class A1<T> {
+}
+extension A2<T> ( ){ }
+on A1<T> (){ }
+extension A3<T extends A1<T>> ( ){ }
+on A1<T> (){ }
+extension A4<T> ( ){ }
+on A1<T> (){ }
+main() { }
diff --git a/pkg/front_end/testcases/extensions/unnamed_extensions.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/unnamed_extensions.dart.textual_outline.expect
new file mode 100644
index 0000000..7a779e4
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/unnamed_extensions.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+class Class1 {
+ int field;
+ Class1(this.field);
+ String toString() => 'Class1($field)';
+}
+class Class2 {
+ int field;
+ Class2(this.field);
+ String toString() => 'Class2($field)';
+}
+extension on ;
+Class1 (){ }
+extension on ;
+Class2 (){ }
+main() { }
+testExtension1() { }
+testExtension2() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/extensions/use_this.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/use_this.dart.textual_outline.expect
new file mode 100644
index 0000000..04526ab
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/use_this.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class A1 {
+}
+extension A2 ;
+on A1 (){ }
+class B1<T> {
+}
+extension B2<T> ( ){ }
+on B1<T> (){ }
+main() { }
diff --git a/pkg/front_end/testcases/general/DeltaBlue.dart.textual_outline.expect b/pkg/front_end/testcases/general/DeltaBlue.dart.textual_outline.expect
new file mode 100644
index 0000000..b0e9877
--- /dev/null
+++ b/pkg/front_end/testcases/general/DeltaBlue.dart.textual_outline.expect
@@ -0,0 +1,153 @@
+main() {}
+
+class DeltaBlue {
+ void run() {}
+}
+
+class Strength {
+ final int value;
+ final String name;
+ const Strength(this.value, this.name);
+ Strength nextWeaker() => const <Strength>[
+ STRONG_PREFERRED,
+ PREFERRED,
+ STRONG_DEFAULT,
+ NORMAL,
+ WEAK_DEFAULT,
+ WEAKEST
+ ][value];
+ static bool stronger(Strength s1, Strength s2) {}
+ static bool weaker(Strength s1, Strength s2) {}
+ static Strength weakest(Strength s1, Strength s2) {}
+ static Strength strongest(Strength s1, Strength s2) {}
+}
+
+const REQUIRED = const Strength(0, "required");
+const STRONG_PREFERRED = const Strength(1, "strongPreferred");
+const PREFERRED = const Strength(2, "preferred");
+const STRONG_DEFAULT = const Strength(3, "strongDefault");
+const NORMAL = const Strength(4, "normal");
+const WEAK_DEFAULT = const Strength(5, "weakDefault");
+const WEAKEST = const Strength(6, "weakest");
+
+abstract class Constraint {
+ final Strength strength;
+ const Constraint(this.strength);
+ bool isSatisfied();
+ void markUnsatisfied();
+ void addToGraph();
+ void removeFromGraph();
+ void chooseMethod(int mark);
+ void markInputs(int mark);
+ bool inputsKnown(int mark);
+ Variable output();
+ void execute();
+ void recalculate();
+ void addConstraint() {}
+ Constraint satisfy(mark) {}
+ void destroyConstraint() {}
+ bool isInput() => false;
+}
+
+abstract class UnaryConstraint extends Constraint {
+ final Variable myOutput;
+ bool satisfied = false;
+ UnaryConstraint(this.myOutput, Strength strength) : super(strength) {}
+ void addToGraph() {}
+ void chooseMethod(int mark) {}
+ bool isSatisfied() => satisfied;
+ void markInputs(int mark) {}
+ Variable output() => myOutput;
+ void recalculate() {}
+ void markUnsatisfied() {}
+ bool inputsKnown(int mark) => true;
+ void removeFromGraph() {}
+}
+
+class StayConstraint extends UnaryConstraint {
+ StayConstraint(Variable v, Strength str) : super(v, str);
+ void execute() {}
+}
+
+class EditConstraint extends UnaryConstraint {
+ EditConstraint(Variable v, Strength str) : super(v, str);
+ bool isInput() => true;
+ void execute() {}
+}
+
+const int NONE = 1;
+const int FORWARD = 2;
+const int BACKWARD = 0;
+
+abstract class BinaryConstraint extends Constraint {
+ Variable v1;
+ Variable v2;
+ int direction = NONE;
+ BinaryConstraint(this.v1, this.v2, Strength strength) : super(strength) {}
+ void chooseMethod(int mark) {}
+ void addToGraph() {}
+ bool isSatisfied() => direction != NONE;
+ void markInputs(int mark) {}
+ Variable input() => direction == FORWARD ? v1 : v2;
+ Variable output() => direction == FORWARD ? v2 : v1;
+ void recalculate() {}
+ void markUnsatisfied() {}
+ bool inputsKnown(int mark) {}
+ void removeFromGraph() {}
+}
+
+class ScaleConstraint extends BinaryConstraint {
+ final Variable scale;
+ final Variable offset;
+ ScaleConstraint(
+ Variable src, this.scale, this.offset, Variable dest, Strength strength)
+ : super(src, dest, strength);
+ void addToGraph() {}
+ void removeFromGraph() {}
+ void markInputs(int mark) {}
+ void execute() {}
+ void recalculate() {}
+}
+
+class EqualityConstraint extends BinaryConstraint {
+ EqualityConstraint(Variable v1, Variable v2, Strength strength)
+ : super(v1, v2, strength);
+ void execute() {}
+}
+
+class Variable {
+ List<Constraint> constraints = <Constraint>[];
+ Constraint determinedBy;
+ int mark = 0;
+ Strength walkStrength = WEAKEST;
+ bool stay = true;
+ int value;
+ final String name;
+ Variable(this.name, this.value);
+ void addConstraint(Constraint c) {}
+ void removeConstraint(Constraint c) {}
+}
+
+class Planner {
+ int currentMark = 0;
+ void incrementalAdd(Constraint c) {}
+ void incrementalRemove(Constraint c) {}
+ int newMark() => ++currentMark;
+ Plan makePlan(List<Constraint> sources) {}
+ Plan extractPlanFromConstraints(List<Constraint> constraints) {}
+ bool addPropagate(Constraint c, int mark) {}
+ List<Constraint> removePropagateFrom(Variable out) {}
+ void addConstraintsConsumingTo(Variable v, List<Constraint> coll) {}
+}
+
+class Plan {
+ List<Constraint> list = <Constraint>[];
+ void addConstraint(Constraint c) {}
+ int size() => list.length;
+ void execute() {}
+}
+
+void chainTest(int n) {}
+void projectionTest(int n) {}
+void change(Variable v, int newValue) {}
+Planner planner;
diff --git a/pkg/front_end/testcases/general/DeltaBlue.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/DeltaBlue.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..43daecc
--- /dev/null
+++ b/pkg/front_end/testcases/general/DeltaBlue.dart.textual_outline_modelled.expect
@@ -0,0 +1,151 @@
+Planner planner;
+
+abstract class BinaryConstraint extends Constraint {
+ BinaryConstraint(this.v1, this.v2, Strength strength) : super(strength) {}
+ Variable input() => direction == FORWARD ? v1 : v2;
+ Variable output() => direction == FORWARD ? v2 : v1;
+ Variable v1;
+ Variable v2;
+ bool inputsKnown(int mark) {}
+ bool isSatisfied() => direction != NONE;
+ int direction = NONE;
+ void addToGraph() {}
+ void chooseMethod(int mark) {}
+ void markInputs(int mark) {}
+ void markUnsatisfied() {}
+ void recalculate() {}
+ void removeFromGraph() {}
+}
+
+abstract class Constraint {
+ Constraint satisfy(mark) {}
+ Variable output();
+ bool inputsKnown(int mark);
+ bool isInput() => false;
+ bool isSatisfied();
+ const Constraint(this.strength);
+ final Strength strength;
+ void addConstraint() {}
+ void addToGraph();
+ void chooseMethod(int mark);
+ void destroyConstraint() {}
+ void execute();
+ void markInputs(int mark);
+ void markUnsatisfied();
+ void recalculate();
+ void removeFromGraph();
+}
+
+abstract class UnaryConstraint extends Constraint {
+ UnaryConstraint(this.myOutput, Strength strength) : super(strength) {}
+ Variable output() => myOutput;
+ bool inputsKnown(int mark) => true;
+ bool isSatisfied() => satisfied;
+ bool satisfied = false;
+ final Variable myOutput;
+ void addToGraph() {}
+ void chooseMethod(int mark) {}
+ void markInputs(int mark) {}
+ void markUnsatisfied() {}
+ void recalculate() {}
+ void removeFromGraph() {}
+}
+
+class DeltaBlue {
+ void run() {}
+}
+
+class EditConstraint extends UnaryConstraint {
+ EditConstraint(Variable v, Strength str) : super(v, str);
+ bool isInput() => true;
+ void execute() {}
+}
+
+class EqualityConstraint extends BinaryConstraint {
+ EqualityConstraint(Variable v1, Variable v2, Strength strength)
+ : super(v1, v2, strength);
+ void execute() {}
+}
+
+class Plan {
+ List<Constraint> list = <Constraint>[];
+ int size() => list.length;
+ void addConstraint(Constraint c) {}
+ void execute() {}
+}
+
+class Planner {
+ List<Constraint> removePropagateFrom(Variable out) {}
+ Plan extractPlanFromConstraints(List<Constraint> constraints) {}
+ Plan makePlan(List<Constraint> sources) {}
+ bool addPropagate(Constraint c, int mark) {}
+ int currentMark = 0;
+ int newMark() => ++currentMark;
+ void addConstraintsConsumingTo(Variable v, List<Constraint> coll) {}
+ void incrementalAdd(Constraint c) {}
+ void incrementalRemove(Constraint c) {}
+}
+
+class ScaleConstraint extends BinaryConstraint {
+ ScaleConstraint(
+ Variable src, this.scale, this.offset, Variable dest, Strength strength)
+ : super(src, dest, strength);
+ final Variable offset;
+ final Variable scale;
+ void addToGraph() {}
+ void execute() {}
+ void markInputs(int mark) {}
+ void recalculate() {}
+ void removeFromGraph() {}
+}
+
+class StayConstraint extends UnaryConstraint {
+ StayConstraint(Variable v, Strength str) : super(v, str);
+ void execute() {}
+}
+
+class Strength {
+ Strength nextWeaker() => const <Strength>[
+ STRONG_PREFERRED,
+ PREFERRED,
+ STRONG_DEFAULT,
+ NORMAL,
+ WEAK_DEFAULT,
+ WEAKEST
+ ][value];
+ const Strength(this.value, this.name);
+ final String name;
+ final int value;
+ static Strength strongest(Strength s1, Strength s2) {}
+ static Strength weakest(Strength s1, Strength s2) {}
+ static bool stronger(Strength s1, Strength s2) {}
+ static bool weaker(Strength s1, Strength s2) {}
+}
+
+class Variable {
+ Constraint determinedBy;
+ List<Constraint> constraints = <Constraint>[];
+ Strength walkStrength = WEAKEST;
+ Variable(this.name, this.value);
+ bool stay = true;
+ final String name;
+ int mark = 0;
+ int value;
+ void addConstraint(Constraint c) {}
+ void removeConstraint(Constraint c) {}
+}
+
+const NORMAL = const Strength(4, "normal");
+const PREFERRED = const Strength(2, "preferred");
+const REQUIRED = const Strength(0, "required");
+const STRONG_DEFAULT = const Strength(3, "strongDefault");
+const STRONG_PREFERRED = const Strength(1, "strongPreferred");
+const WEAKEST = const Strength(6, "weakest");
+const WEAK_DEFAULT = const Strength(5, "weakDefault");
+const int BACKWARD = 0;
+const int FORWARD = 2;
+const int NONE = 1;
+main() {}
+void chainTest(int n) {}
+void change(Variable v, int newValue) {}
+void projectionTest(int n) {}
diff --git a/pkg/front_end/testcases/general/abstract_members.dart.textual_outline.expect b/pkg/front_end/testcases/general/abstract_members.dart.textual_outline.expect
new file mode 100644
index 0000000..866053c
--- /dev/null
+++ b/pkg/front_end/testcases/general/abstract_members.dart.textual_outline.expect
@@ -0,0 +1,80 @@
+class Interface1 {
+ void interfaceMethod1() {}
+}
+
+class Interface2 {
+ void interfaceMethod2() {}
+ var interfaceMethod1;
+}
+
+class Interface3 {
+ void interfaceMethod3() {}
+}
+
+abstract class A implements Interface1, Interface2, Interface3 {
+ aMethod() {}
+ abstractMethod();
+ void set property1(_);
+ void set property2(_);
+ void set property3(_);
+}
+
+abstract class B extends A {
+ final property1 = null;
+ aMethod() {}
+ bMethod() {}
+}
+
+class MyClass extends B {
+ var property2;
+ aaMethod() {}
+ aMethod() {}
+ bMethod() {}
+ cMethod() {}
+}
+
+class MyMock1 extends B {
+ noSuchMethod(_) => null;
+}
+
+class MyMock2 extends MyMock1 {
+ noSuchMethod(_);
+}
+
+class MyMock3 extends B {
+ noSuchMethod(_);
+}
+
+class C {
+ void interfaceMethod1(_) {}
+}
+
+abstract class D extends C implements Interface2 {}
+
+class E {
+ void set interfaceMethod1(_) {}
+}
+
+abstract class F extends E implements Interface1 {}
+
+class Foo {
+ void foo() {}
+}
+
+class G {
+ Object get foo => null;
+}
+
+abstract class H extends G implements Foo {}
+
+class Bar {
+ Object get foo => null;
+}
+
+class I {
+ Object foo() {}
+}
+
+abstract class J extends I implements Bar {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/abstract_members.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/abstract_members.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..77e8755
--- /dev/null
+++ b/pkg/front_end/testcases/general/abstract_members.dart.textual_outline_modelled.expect
@@ -0,0 +1,80 @@
+abstract class A implements Interface1, Interface2, Interface3 {
+ aMethod() {}
+ abstractMethod();
+ void set property1(_);
+ void set property2(_);
+ void set property3(_);
+}
+
+abstract class B extends A {
+ aMethod() {}
+ bMethod() {}
+ final property1 = null;
+}
+
+abstract class D extends C implements Interface2 {}
+
+abstract class F extends E implements Interface1 {}
+
+abstract class H extends G implements Foo {}
+
+abstract class J extends I implements Bar {}
+
+class Bar {
+ Object get foo => null;
+}
+
+class C {
+ void interfaceMethod1(_) {}
+}
+
+class E {
+ void set interfaceMethod1(_) {}
+}
+
+class Foo {
+ void foo() {}
+}
+
+class G {
+ Object get foo => null;
+}
+
+class I {
+ Object foo() {}
+}
+
+class Interface1 {
+ void interfaceMethod1() {}
+}
+
+class Interface2 {
+ var interfaceMethod1;
+ void interfaceMethod2() {}
+}
+
+class Interface3 {
+ void interfaceMethod3() {}
+}
+
+class MyClass extends B {
+ aMethod() {}
+ aaMethod() {}
+ bMethod() {}
+ cMethod() {}
+ var property2;
+}
+
+class MyMock1 extends B {
+ noSuchMethod(_) => null;
+}
+
+class MyMock2 extends MyMock1 {
+ noSuchMethod(_);
+}
+
+class MyMock3 extends B {
+ noSuchMethod(_);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/abstract_overrides_concrete_with_no_such_method.dart.textual_outline.expect b/pkg/front_end/testcases/general/abstract_overrides_concrete_with_no_such_method.dart.textual_outline.expect
new file mode 100644
index 0000000..a22c063
--- /dev/null
+++ b/pkg/front_end/testcases/general/abstract_overrides_concrete_with_no_such_method.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+abstract class A {
+ A foo() => null;
+}
+
+abstract class B extends A {
+ B foo();
+}
+
+class C {
+ noSuchMethod(_) => null;
+}
+
+class D extends C implements B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/abstract_overrides_concrete_with_no_such_method.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/abstract_overrides_concrete_with_no_such_method.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a22c063
--- /dev/null
+++ b/pkg/front_end/testcases/general/abstract_overrides_concrete_with_no_such_method.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+abstract class A {
+ A foo() => null;
+}
+
+abstract class B extends A {
+ B foo();
+}
+
+class C {
+ noSuchMethod(_) => null;
+}
+
+class D extends C implements B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/accessors.dart.textual_outline.expect b/pkg/front_end/testcases/general/accessors.dart.textual_outline.expect
new file mode 100644
index 0000000..9c4a898
--- /dev/null
+++ b/pkg/front_end/testcases/general/accessors.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+void set onlySetter(value) {}
+
+class C {
+ void set onlySetter(value) {}
+ testC() {}
+ testD() {}
+}
+
+class D extends C {
+ String get onlySetter => "D.onlySetter called.";
+ void set onlySetter(value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/accessors.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/accessors.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3072e99
--- /dev/null
+++ b/pkg/front_end/testcases/general/accessors.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+class C {
+ testC() {}
+ testD() {}
+ void set onlySetter(value) {}
+}
+
+class D extends C {
+ String get onlySetter => "D.onlySetter called.";
+ void set onlySetter(value) {}
+}
+
+main() {}
+void set onlySetter(value) {}
diff --git a/pkg/front_end/testcases/general/all_variances.dart.textual_outline.expect b/pkg/front_end/testcases/general/all_variances.dart.textual_outline.expect
new file mode 100644
index 0000000..e174256
--- /dev/null
+++ b/pkg/front_end/testcases/general/all_variances.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+typedef F<W, X, Y, Z> = X Function(Y, Z Function(Z));
+main() {}
diff --git a/pkg/front_end/testcases/general/all_variances.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/all_variances.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..487ff53
--- /dev/null
+++ b/pkg/front_end/testcases/general/all_variances.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+main() {}
+typedef F<W, X, Y, Z> = X Function(Y, Z Function(Z));
diff --git a/pkg/front_end/testcases/general/ambiguous_exports.dart.textual_outline.expect b/pkg/front_end/testcases/general/ambiguous_exports.dart.textual_outline.expect
new file mode 100644
index 0000000..7fe554b
--- /dev/null
+++ b/pkg/front_end/testcases/general/ambiguous_exports.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+export 'hello.dart' show main;
+export 'map.dart' show main;
diff --git a/pkg/front_end/testcases/general/ambiguous_exports.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/ambiguous_exports.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7fe554b
--- /dev/null
+++ b/pkg/front_end/testcases/general/ambiguous_exports.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+export 'hello.dart' show main;
+export 'map.dart' show main;
diff --git a/pkg/front_end/testcases/general/annotation_eof.dart.textual_outline.expect b/pkg/front_end/testcases/general/annotation_eof.dart.textual_outline.expect
new file mode 100644
index 0000000..4f0c503
--- /dev/null
+++ b/pkg/front_end/testcases/general/annotation_eof.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+main() { }
+@AnnotationAtEOF
diff --git a/pkg/front_end/testcases/general/annotation_on_enum_values.dart.textual_outline.expect b/pkg/front_end/testcases/general/annotation_on_enum_values.dart.textual_outline.expect
new file mode 100644
index 0000000..42c4aa9
--- /dev/null
+++ b/pkg/front_end/testcases/general/annotation_on_enum_values.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+const int hest = 42;
+
+class Fisk<T> {
+ final T x;
+ const Fisk.fisk(this.x);
+}
+
+enum Foo {
+ @hest
+ bar,
+ @Fisk.fisk(hest)
+ baz,
+ cafebabe,
+}
+main() {}
diff --git a/pkg/front_end/testcases/general/annotation_on_enum_values.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/annotation_on_enum_values.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1866609
--- /dev/null
+++ b/pkg/front_end/testcases/general/annotation_on_enum_values.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+class Fisk<T> {
+ const Fisk.fisk(this.x);
+ final T x;
+}
+
+const int hest = 42;
+enum Foo {
+ @hest
+ bar,
+ @Fisk.fisk(hest)
+ baz,
+ cafebabe,
+}
+main() {}
diff --git a/pkg/front_end/testcases/general/annotation_top.dart.textual_outline.expect b/pkg/front_end/testcases/general/annotation_top.dart.textual_outline.expect
new file mode 100644
index 0000000..579bc70
--- /dev/null
+++ b/pkg/front_end/testcases/general/annotation_top.dart.textual_outline.expect
@@ -0,0 +1,26 @@
+@a
+@A(1)
+library test;
+
+const Object a = const Object();
+
+class A {
+ const A(int value);
+}
+
+@a
+@A(2)
+class C {}
+
+@a
+@A(2)
+typedef void F1();
+@a
+@A(3)
+typedef F2 = void Function();
+@a
+@A(3)
+int f1, f2;
+@a
+@A(4)
+void main() {}
diff --git a/pkg/front_end/testcases/general/annotation_top.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/annotation_top.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..faefe48
--- /dev/null
+++ b/pkg/front_end/testcases/general/annotation_top.dart.textual_outline_modelled.expect
@@ -0,0 +1,26 @@
+@a
+@A(1)
+library test;
+
+@a
+@A(2)
+class C {}
+
+@a
+@A(2)
+typedef void F1();
+@a
+@A(3)
+int f1, f2;
+@a
+@A(3)
+typedef F2 = void Function();
+@a
+@A(4)
+void main() {}
+
+class A {
+ const A(int value);
+}
+
+const Object a = const Object();
diff --git a/pkg/front_end/testcases/general/annotation_typedef_formals.dart.textual_outline.expect b/pkg/front_end/testcases/general/annotation_typedef_formals.dart.textual_outline.expect
new file mode 100644
index 0000000..15fb5d5
--- /dev/null
+++ b/pkg/front_end/testcases/general/annotation_typedef_formals.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+const int foo = 21;
+const int bar = 42;
+const int baz = 84;
+typedef void F(@foo int x, num y, {@bar @baz String z, Object w});
+typedef void G(@foo int a, num b, [@bar @baz String c, Object d]);
+main() {}
diff --git a/pkg/front_end/testcases/general/annotation_typedef_formals.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/annotation_typedef_formals.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b301156
--- /dev/null
+++ b/pkg/front_end/testcases/general/annotation_typedef_formals.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+const int bar = 42;
+const int baz = 84;
+const int foo = 21;
+main() {}
+typedef void F(@foo int x, num y, {@bar @baz String z, Object w});
+typedef void G(@foo int a, num b, [@bar @baz String c, Object d]);
diff --git a/pkg/front_end/testcases/general/annotation_typedef_formals_resolution.dart.textual_outline.expect b/pkg/front_end/testcases/general/annotation_typedef_formals_resolution.dart.textual_outline.expect
new file mode 100644
index 0000000..31a5a66
--- /dev/null
+++ b/pkg/front_end/testcases/general/annotation_typedef_formals_resolution.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+const int app = 0;
+typedef int F(@app int app);
+main() {}
diff --git a/pkg/front_end/testcases/general/annotation_typedef_formals_resolution.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/annotation_typedef_formals_resolution.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e353a08
--- /dev/null
+++ b/pkg/front_end/testcases/general/annotation_typedef_formals_resolution.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+const int app = 0;
+main() {}
+typedef int F(@app int app);
diff --git a/pkg/front_end/testcases/general/annotation_variable_declaration.dart.textual_outline.expect b/pkg/front_end/testcases/general/annotation_variable_declaration.dart.textual_outline.expect
new file mode 100644
index 0000000..52559a9
--- /dev/null
+++ b/pkg/front_end/testcases/general/annotation_variable_declaration.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+const int foo = 42;
+
+class Bar {
+ const Bar();
+ const Bar.named(x);
+}
+
+class Baz {
+ Baz(@foo constructorFormal);
+ factory Baz.bazFactory(@foo factoryFormal) => null;
+ fisk(@foo formal1, @Bar() formal2, @Bar.named(foo) formal3,
+ @foo @Bar.named(foo) formal4,
+ [@foo optional]) {}
+ hest({@foo named}) => null;
+}
+
+typedef hest_t({@foo named});
+main() {}
diff --git a/pkg/front_end/testcases/general/annotation_variable_declaration.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/annotation_variable_declaration.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1a18629
--- /dev/null
+++ b/pkg/front_end/testcases/general/annotation_variable_declaration.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+class Bar {
+ const Bar();
+ const Bar.named(x);
+}
+
+class Baz {
+ Baz(@foo constructorFormal);
+ factory Baz.bazFactory(@foo factoryFormal) => null;
+ fisk(@foo formal1, @Bar() formal2, @Bar.named(foo) formal3,
+ @foo @Bar.named(foo) formal4,
+ [@foo optional]) {}
+ hest({@foo named}) => null;
+}
+
+const int foo = 42;
+main() {}
+typedef hest_t({@foo named});
diff --git a/pkg/front_end/testcases/general/argument.dart.textual_outline.expect b/pkg/front_end/testcases/general/argument.dart.textual_outline.expect
new file mode 100644
index 0000000..09a1fdd
--- /dev/null
+++ b/pkg/front_end/testcases/general/argument.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+abstract class Base {}
+
+class Foo extends Base {}
+
+class Bar extends Base {}
+
+class Baz extends Base {}
+
+void foo(x) {}
+void bar(x) {}
+void foo_escaped(x) {}
+void bar_escaped(x) {}
+void escape(fn) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/argument.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/argument.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3150668
--- /dev/null
+++ b/pkg/front_end/testcases/general/argument.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+abstract class Base {}
+
+class Bar extends Base {}
+
+class Baz extends Base {}
+
+class Foo extends Base {}
+
+main() {}
+void bar(x) {}
+void bar_escaped(x) {}
+void escape(fn) {}
+void foo(x) {}
+void foo_escaped(x) {}
diff --git a/pkg/front_end/testcases/general/argument_mismatch.dart.textual_outline.expect b/pkg/front_end/testcases/general/argument_mismatch.dart.textual_outline.expect
new file mode 100644
index 0000000..3b58842
--- /dev/null
+++ b/pkg/front_end/testcases/general/argument_mismatch.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+foo() {}
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/argument_mismatch.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/argument_mismatch.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1391a6a
--- /dev/null
+++ b/pkg/front_end/testcases/general/argument_mismatch.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+foo() {}
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/arithmetic.dart.textual_outline.expect b/pkg/front_end/testcases/general/arithmetic.dart.textual_outline.expect
new file mode 100644
index 0000000..5c6fdec
--- /dev/null
+++ b/pkg/front_end/testcases/general/arithmetic.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+int foo(int x, int y) {}
+void loop(List xs) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/arithmetic.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/arithmetic.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d2e4a11
--- /dev/null
+++ b/pkg/front_end/testcases/general/arithmetic.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+int foo(int x, int y) {}
+main() {}
+void loop(List xs) {}
diff --git a/pkg/front_end/testcases/general/arrow_function.dart.textual_outline.expect b/pkg/front_end/testcases/general/arrow_function.dart.textual_outline.expect
new file mode 100644
index 0000000..b66ca49
--- /dev/null
+++ b/pkg/front_end/testcases/general/arrow_function.dart.textual_outline.expect
@@ -0,0 +1 @@
+main<T>() => () => T;
diff --git a/pkg/front_end/testcases/general/arrow_function.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/arrow_function.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b66ca49
--- /dev/null
+++ b/pkg/front_end/testcases/general/arrow_function.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main<T>() => () => T;
diff --git a/pkg/front_end/testcases/general/assign_to_initializing_formal.dart.textual_outline.expect b/pkg/front_end/testcases/general/assign_to_initializing_formal.dart.textual_outline.expect
new file mode 100644
index 0000000..0ee755e
--- /dev/null
+++ b/pkg/front_end/testcases/general/assign_to_initializing_formal.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+import "package:expect/expect.dart";
+
+class A {
+ var x, y;
+ A(this.x)
+ : y = (() {
+ x = 3;
+ });
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/assign_to_initializing_formal.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/assign_to_initializing_formal.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4d7dc12
--- /dev/null
+++ b/pkg/front_end/testcases/general/assign_to_initializing_formal.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+import "package:expect/expect.dart";
+
+class A {
+ A(this.x)
+ : y = (() {
+ x = 3;
+ });
+ var x, y;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/async_function.dart.textual_outline.expect b/pkg/front_end/testcases/general/async_function.dart.textual_outline.expect
new file mode 100644
index 0000000..20ff937
--- /dev/null
+++ b/pkg/front_end/testcases/general/async_function.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+import 'dart:async';
+
+Future<String> asyncString() async {}
+Future<String> asyncString2() async {}
+Iterable<String> syncStarString() sync* {}
+Iterable<String> syncStarString2() sync* {}
+Stream<String> asyncStarString() async* {}
+Stream<String> asyncStarString2() async* {}
+List<String> stringList = ["bar"];
+main() async {}
diff --git a/pkg/front_end/testcases/general/async_function.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/async_function.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2451edd
--- /dev/null
+++ b/pkg/front_end/testcases/general/async_function.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+import 'dart:async';
+
+Future<String> asyncString() async {}
+Future<String> asyncString2() async {}
+Iterable<String> syncStarString() sync* {}
+Iterable<String> syncStarString2() sync* {}
+List<String> stringList = ["bar"];
+Stream<String> asyncStarString() async* {}
+Stream<String> asyncStarString2() async* {}
+main() async {}
diff --git a/pkg/front_end/testcases/general/async_nested.dart.textual_outline.expect b/pkg/front_end/testcases/general/async_nested.dart.textual_outline.expect
new file mode 100644
index 0000000..01c5288
--- /dev/null
+++ b/pkg/front_end/testcases/general/async_nested.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+import 'dart:async';
+
+void main() async {}
+
+class Node {
+ final List<Node> nested;
+ final String name;
+ Node(this.name, [this.nested]) {}
+ String toString() => '<$name:[${nested?.join(', ')}]>';
+ toSimpleString() {}
+}
diff --git a/pkg/front_end/testcases/general/async_nested.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/async_nested.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8be533c
--- /dev/null
+++ b/pkg/front_end/testcases/general/async_nested.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+import 'dart:async';
+
+class Node {
+ Node(this.name, [this.nested]) {}
+ String toString() => '<$name:[${nested?.join(', ')}]>';
+ final List<Node> nested;
+ final String name;
+ toSimpleString() {}
+}
+
+void main() async {}
diff --git a/pkg/front_end/testcases/general/await.dart.textual_outline.expect b/pkg/front_end/testcases/general/await.dart.textual_outline.expect
new file mode 100644
index 0000000..386f405
--- /dev/null
+++ b/pkg/front_end/testcases/general/await.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() async {}
diff --git a/pkg/front_end/testcases/general/await.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/await.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..386f405
--- /dev/null
+++ b/pkg/front_end/testcases/general/await.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() async {}
diff --git a/pkg/front_end/testcases/general/await_complex.dart.textual_outline.expect b/pkg/front_end/testcases/general/await_complex.dart.textual_outline.expect
new file mode 100644
index 0000000..16785e4
--- /dev/null
+++ b/pkg/front_end/testcases/general/await_complex.dart.textual_outline.expect
@@ -0,0 +1,40 @@
+import 'dart:async';
+
+int globalVariable = 1;
+int topLevelFoo(int param) => 1;
+int get topLevelGetter => globalVariable;
+void set topLevelSetter(val) {}
+
+class C {
+ static int staticField = 1;
+ static int get staticGetter => staticField;
+ static void set staticSetter(val) {}
+ static int staticFoo(int param) => param;
+ int field = 1;
+ int get getter => field;
+ void set setter(val) {}
+ int foo(int param) => param;
+}
+
+dummy() => 1;
+staticMembers() async {}
+topLevelMembers() async {}
+instanceMembers() async {}
+others() async {}
+conditionals() async {}
+asserts() async {}
+controlFlow() async {}
+FutureOr<T> future<T>(T value) async => value;
+FutureOr<T> id<T>(T value) => value;
+Stream<int> intStream() async* {}
+final bool assertStatementsEnabled = () {
+ try {
+ assert(false);
+ return false;
+ } catch (_) {
+ return true;
+ }
+}();
+main() async {}
+expect(expected, actual) {}
+expectList(List expected, List actual) {}
diff --git a/pkg/front_end/testcases/general/await_complex.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/await_complex.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ddaab5f
--- /dev/null
+++ b/pkg/front_end/testcases/general/await_complex.dart.textual_outline_modelled.expect
@@ -0,0 +1,40 @@
+import 'dart:async';
+
+FutureOr<T> future<T>(T value) async => value;
+FutureOr<T> id<T>(T value) => value;
+Stream<int> intStream() async* {}
+asserts() async {}
+
+class C {
+ int field = 1;
+ int foo(int param) => param;
+ int get getter => field;
+ static int get staticGetter => staticField;
+ static int staticField = 1;
+ static int staticFoo(int param) => param;
+ static void set staticSetter(val) {}
+ void set setter(val) {}
+}
+
+conditionals() async {}
+controlFlow() async {}
+dummy() => 1;
+expect(expected, actual) {}
+expectList(List expected, List actual) {}
+final bool assertStatementsEnabled = () {
+ try {
+ assert(false);
+ return false;
+ } catch (_) {
+ return true;
+ }
+}();
+instanceMembers() async {}
+int get topLevelGetter => globalVariable;
+int globalVariable = 1;
+int topLevelFoo(int param) => 1;
+main() async {}
+others() async {}
+staticMembers() async {}
+topLevelMembers() async {}
+void set topLevelSetter(val) {}
diff --git a/pkg/front_end/testcases/general/await_in_cascade.dart.textual_outline.expect b/pkg/front_end/testcases/general/await_in_cascade.dart.textual_outline.expect
new file mode 100644
index 0000000..543028a
--- /dev/null
+++ b/pkg/front_end/testcases/general/await_in_cascade.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+import 'dart:async';
+
+class C {
+ Future<List<int>> m() async => []..add(await _m());
+ Future<int> _m() async => 42;
+}
+
+main() async {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/general/await_in_cascade.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/await_in_cascade.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..305a56e
--- /dev/null
+++ b/pkg/front_end/testcases/general/await_in_cascade.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+import 'dart:async';
+
+class C {
+ Future<List<int>> m() async => []..add(await _m());
+ Future<int> _m() async => 42;
+}
+
+expect(expected, actual) {}
+main() async {}
diff --git a/pkg/front_end/testcases/general/await_in_non_async.dart.textual_outline.expect b/pkg/front_end/testcases/general/await_in_non_async.dart.textual_outline.expect
new file mode 100644
index 0000000..afc9a41
--- /dev/null
+++ b/pkg/front_end/testcases/general/await_in_non_async.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+main() {}
+foo() {}
diff --git a/pkg/front_end/testcases/general/await_in_non_async.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/await_in_non_async.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d530fa8
--- /dev/null
+++ b/pkg/front_end/testcases/general/await_in_non_async.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/bad_setter_abstract.dart.textual_outline.expect b/pkg/front_end/testcases/general/bad_setter_abstract.dart.textual_outline.expect
new file mode 100644
index 0000000..dbf31c9
--- /dev/null
+++ b/pkg/front_end/testcases/general/bad_setter_abstract.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+set b();
+set c(x, y);
+class A {
+ set a();
+ set d(x, y);
+}
+abstract class B {
+ set a();
+ set d(x, y);
+}
+main() { }
diff --git a/pkg/front_end/testcases/general/bad_store.dart.textual_outline.expect b/pkg/front_end/testcases/general/bad_store.dart.textual_outline.expect
new file mode 100644
index 0000000..1749c06
--- /dev/null
+++ b/pkg/front_end/testcases/general/bad_store.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class Foo {
+ var field;
+}
+
+dynamic identity(x) => x;
+void use(x) {}
+main(List<String> args) {}
diff --git a/pkg/front_end/testcases/general/bad_store.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/bad_store.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1745116
--- /dev/null
+++ b/pkg/front_end/testcases/general/bad_store.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class Foo {
+ var field;
+}
+
+dynamic identity(x) => x;
+main(List<String> args) {}
+void use(x) {}
diff --git a/pkg/front_end/testcases/general/bad_type_variable_uses_in_supertypes.dart.textual_outline.expect b/pkg/front_end/testcases/general/bad_type_variable_uses_in_supertypes.dart.textual_outline.expect
new file mode 100644
index 0000000..c9ae869
--- /dev/null
+++ b/pkg/front_end/testcases/general/bad_type_variable_uses_in_supertypes.dart.textual_outline.expect
@@ -0,0 +1,78 @@
+typedef ContravariantUse<T> = Function(T);
+typedef InvariantUse<T> = T Function(T);
+
+class Empty {}
+
+class A<T> {}
+
+class B<T> extends A<Function(T)> {}
+
+class Bc<T> extends A<ContravariantUse<T>> {}
+
+class Bi<T> extends A<InvariantUse<T>> {}
+
+class C<T> implements A<Function(T)> {}
+
+class Cc<T> implements A<ContravariantUse<T>> {}
+
+class Ci<T> implements A<InvariantUse<T>> {}
+
+class D<T> = Object with A<Function(T)>;
+class Dc<T> = Object with A<ContravariantUse<T>>;
+class Di<T> = Object with A<InvariantUse<T>>;
+class E<T> = A<Function(T)> with Empty;
+class Ec<T> = A<ContravariantUse<T>> with Empty;
+class Ei<T> = A<InvariantUse<T>> with Empty;
+
+class F<T> extends Object with A<Function(T)> {}
+
+class Fc<T> extends Object with A<ContravariantUse<T>> {}
+
+class Fi<T> extends Object with A<InvariantUse<T>> {}
+
+class G<T> extends A<Function(T)> with Empty {}
+
+class Gc<T> extends A<ContravariantUse<T>> with Empty {}
+
+class Gi<T> extends A<InvariantUse<T>> with Empty {}
+
+class Hff<T> extends A<Function(Function(T))> {}
+
+class Hfc<T> extends A<Function(ContravariantUse<T>)> {}
+
+class Hcf<T> extends A<ContravariantUse<Function(T)>> {}
+
+class Hcc<T> extends A<ContravariantUse<ContravariantUse<T>>> {}
+
+class Hii<T> extends A<InvariantUse<InvariantUse<T>>> {}
+
+class Iafc<T> extends A<A<Function(ContravariantUse<T>)>> {}
+
+class Iacf<T> extends A<A<ContravariantUse<Function(T)>>> {}
+
+class Ifac<T> extends A<Function(A<ContravariantUse<T>>)> {}
+
+class Ifca<T> extends A<Function(ContravariantUse<A<T>>)> {}
+
+class Icaf<T> extends A<ContravariantUse<A<Function(T)>>> {}
+
+class Icfa<T> extends A<ContravariantUse<Function(A<T>)>> {}
+
+class Jfff<T> extends A<Function(Function(Function(T)))> {}
+
+class Jffc<T> extends A<Function(Function(ContravariantUse<T>))> {}
+
+class Jfcf<T> extends A<Function(ContravariantUse<Function(T)>)> {}
+
+class Jfcc<T> extends A<Function(ContravariantUse<ContravariantUse<T>>)> {}
+
+class Jcff<T> extends A<ContravariantUse<Function(Function(T))>> {}
+
+class Jcfc<T> extends A<ContravariantUse<Function(ContravariantUse<T>)>> {}
+
+class Jccf<T> extends A<ContravariantUse<ContravariantUse<Function(T)>>> {}
+
+class Jccc<T>
+ extends A<ContravariantUse<ContravariantUse<ContravariantUse<T>>>> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/bad_type_variable_uses_in_supertypes.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/bad_type_variable_uses_in_supertypes.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2ebaf0c
--- /dev/null
+++ b/pkg/front_end/testcases/general/bad_type_variable_uses_in_supertypes.dart.textual_outline_modelled.expect
@@ -0,0 +1,77 @@
+class A<T> {}
+
+class B<T> extends A<Function(T)> {}
+
+class Bc<T> extends A<ContravariantUse<T>> {}
+
+class Bi<T> extends A<InvariantUse<T>> {}
+
+class C<T> implements A<Function(T)> {}
+
+class Cc<T> implements A<ContravariantUse<T>> {}
+
+class Ci<T> implements A<InvariantUse<T>> {}
+
+class Empty {}
+
+typedef ContravariantUse<T> = Function(T);
+typedef InvariantUse<T> = T Function(T);
+class D<T> = Object with A<Function(T)>;
+class Dc<T> = Object with A<ContravariantUse<T>>;
+class Di<T> = Object with A<InvariantUse<T>>;
+class E<T> = A<Function(T)> with Empty;
+class Ec<T> = A<ContravariantUse<T>> with Empty;
+class Ei<T> = A<InvariantUse<T>> with Empty;
+
+class F<T> extends Object with A<Function(T)> {}
+
+class Fc<T> extends Object with A<ContravariantUse<T>> {}
+
+class Fi<T> extends Object with A<InvariantUse<T>> {}
+
+class G<T> extends A<Function(T)> with Empty {}
+
+class Gc<T> extends A<ContravariantUse<T>> with Empty {}
+
+class Gi<T> extends A<InvariantUse<T>> with Empty {}
+
+class Hcc<T> extends A<ContravariantUse<ContravariantUse<T>>> {}
+
+class Hcf<T> extends A<ContravariantUse<Function(T)>> {}
+
+class Hfc<T> extends A<Function(ContravariantUse<T>)> {}
+
+class Hff<T> extends A<Function(Function(T))> {}
+
+class Hii<T> extends A<InvariantUse<InvariantUse<T>>> {}
+
+class Iacf<T> extends A<A<ContravariantUse<Function(T)>>> {}
+
+class Iafc<T> extends A<A<Function(ContravariantUse<T>)>> {}
+
+class Icaf<T> extends A<ContravariantUse<A<Function(T)>>> {}
+
+class Icfa<T> extends A<ContravariantUse<Function(A<T>)>> {}
+
+class Ifac<T> extends A<Function(A<ContravariantUse<T>>)> {}
+
+class Ifca<T> extends A<Function(ContravariantUse<A<T>>)> {}
+
+class Jccc<T>
+ extends A<ContravariantUse<ContravariantUse<ContravariantUse<T>>>> {}
+
+class Jccf<T> extends A<ContravariantUse<ContravariantUse<Function(T)>>> {}
+
+class Jcfc<T> extends A<ContravariantUse<Function(ContravariantUse<T>)>> {}
+
+class Jcff<T> extends A<ContravariantUse<Function(Function(T))>> {}
+
+class Jfcc<T> extends A<Function(ContravariantUse<ContravariantUse<T>>)> {}
+
+class Jfcf<T> extends A<Function(ContravariantUse<Function(T)>)> {}
+
+class Jffc<T> extends A<Function(Function(ContravariantUse<T>))> {}
+
+class Jfff<T> extends A<Function(Function(Function(T)))> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/bounds_check_depends_on_inference.dart.textual_outline.expect b/pkg/front_end/testcases/general/bounds_check_depends_on_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..1b987ae
--- /dev/null
+++ b/pkg/front_end/testcases/general/bounds_check_depends_on_inference.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class A<X> {
+ bar<Y extends X>() => null;
+}
+
+class B {
+ static A<Y> foo<Y extends Object>() => null;
+}
+
+baz() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/bounds_check_depends_on_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/bounds_check_depends_on_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..da490d2
--- /dev/null
+++ b/pkg/front_end/testcases/general/bounds_check_depends_on_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+baz() {}
+
+class A<X> {
+ bar<Y extends X>() => null;
+}
+
+class B {
+ static A<Y> foo<Y extends Object>() => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/bug21938.dart.textual_outline.expect b/pkg/front_end/testcases/general/bug21938.dart.textual_outline.expect
new file mode 100644
index 0000000..ec6b9e0
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug21938.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/bug21938.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/bug21938.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f67dbb0
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug21938.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/bug30695.dart.textual_outline.expect b/pkg/front_end/testcases/general/bug30695.dart.textual_outline.expect
new file mode 100644
index 0000000..8f35078
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug30695.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class A {
+ var foo = 42;
+}
+
+class B extends A {
+ foo() => 42;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/bug30695.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/bug30695.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8f35078
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug30695.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class A {
+ var foo = 42;
+}
+
+class B extends A {
+ foo() => 42;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/bug31124.dart.textual_outline.expect b/pkg/front_end/testcases/general/bug31124.dart.textual_outline.expect
new file mode 100644
index 0000000..331dc8b
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug31124.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+var a = () => 'b';
+a();
diff --git a/pkg/front_end/testcases/general/bug32414a.dart.textual_outline.expect b/pkg/front_end/testcases/general/bug32414a.dart.textual_outline.expect
new file mode 100644
index 0000000..41786bb
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug32414a.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+void test() {}
+void main() {}
diff --git a/pkg/front_end/testcases/general/bug32414a.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/bug32414a.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0e0980f
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug32414a.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+void main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/general/bug32414b.dart.textual_outline.expect b/pkg/front_end/testcases/general/bug32414b.dart.textual_outline.expect
new file mode 100644
index 0000000..41786bb
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug32414b.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+void test() {}
+void main() {}
diff --git a/pkg/front_end/testcases/general/bug32414b.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/bug32414b.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0e0980f
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug32414b.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+void main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/general/bug32426.dart.textual_outline.expect b/pkg/front_end/testcases/general/bug32426.dart.textual_outline.expect
new file mode 100644
index 0000000..9a90eda
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug32426.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+abstract class I {
+ void call();
+}
+
+class C implements I {
+ void call([int x]) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/bug32426.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/bug32426.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9a90eda
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug32426.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+abstract class I {
+ void call();
+}
+
+class C implements I {
+ void call([int x]) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/bug32629.dart.textual_outline.expect b/pkg/front_end/testcases/general/bug32629.dart.textual_outline.expect
new file mode 100644
index 0000000..79a8b78
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug32629.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+class A {
+ dynamic call(dynamic a, dynamic b) {}
+}
+
+typedef S Reducer<S>(S a, dynamic b);
+void foo<S>(Reducer<S> v) {}
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/bug32629.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/bug32629.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..499e1c6
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug32629.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+class A {
+ dynamic call(dynamic a, dynamic b) {}
+}
+
+main() {}
+typedef S Reducer<S>(S a, dynamic b);
+void foo<S>(Reducer<S> v) {}
+void test() {}
diff --git a/pkg/front_end/testcases/general/bug32866.dart.textual_outline.expect b/pkg/front_end/testcases/general/bug32866.dart.textual_outline.expect
new file mode 100644
index 0000000..8207658
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug32866.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+abstract class B {
+ String get f;
+}
+
+class A implements B {
+ final f;
+ A(this.f);
+}
+
+var a = new A("foo");
+main() => print(a);
diff --git a/pkg/front_end/testcases/general/bug32866.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/bug32866.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9acbfae
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug32866.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+abstract class B {
+ String get f;
+}
+
+class A implements B {
+ A(this.f);
+ final f;
+}
+
+main() => print(a);
+var a = new A("foo");
diff --git a/pkg/front_end/testcases/general/bug33099.dart.textual_outline.expect b/pkg/front_end/testcases/general/bug33099.dart.textual_outline.expect
new file mode 100644
index 0000000..dfdc73b
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug33099.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+import 'dart:mirrors';
+
+const _FailingTest failingTest = const _FailingTest();
+
+class _FailingTest {
+ const _FailingTest();
+}
+
+class MyTest {
+ @failingTest
+ void foo() {}
+}
+
+class MyTest2 extends Object with MyTest {}
+
+main() {}
+bool _hasFailingTestAnnotation(MethodMirror method) {}
+bool _hasAnnotationInstance(DeclarationMirror declaration, instance) =>
+ declaration.metadata.any((InstanceMirror annotation) {
+ print('annotation: ${annotation.reflectee}');
+ return identical(annotation.reflectee, instance);
+ });
diff --git a/pkg/front_end/testcases/general/bug33099.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/bug33099.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4aa3b4d
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug33099.dart.textual_outline_modelled.expect
@@ -0,0 +1,22 @@
+import 'dart:mirrors';
+
+bool _hasAnnotationInstance(DeclarationMirror declaration, instance) =>
+ declaration.metadata.any((InstanceMirror annotation) {
+ print('annotation: ${annotation.reflectee}');
+ return identical(annotation.reflectee, instance);
+ });
+bool _hasFailingTestAnnotation(MethodMirror method) {}
+
+class MyTest {
+ @failingTest
+ void foo() {}
+}
+
+class MyTest2 extends Object with MyTest {}
+
+class _FailingTest {
+ const _FailingTest();
+}
+
+const _FailingTest failingTest = const _FailingTest();
+main() {}
diff --git a/pkg/front_end/testcases/general/bug33196.dart.textual_outline.expect b/pkg/front_end/testcases/general/bug33196.dart.textual_outline.expect
new file mode 100644
index 0000000..527244a
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug33196.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'dart:async';
+
+main() {}
+FutureOr<String> returnsString() async {}
diff --git a/pkg/front_end/testcases/general/bug33196.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/bug33196.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..66d5579
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug33196.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'dart:async';
+
+FutureOr<String> returnsString() async {}
+main() {}
diff --git a/pkg/front_end/testcases/general/bug33206.dart.textual_outline.expect b/pkg/front_end/testcases/general/bug33206.dart.textual_outline.expect
new file mode 100644
index 0000000..1d7feb68
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug33206.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+import 'dart:async';
+
+class X {
+ final x;
+ final y;
+ X(this.x, this.y);
+ toString() => "X($x, $y)";
+}
+
+class Y {
+ f(_) {}
+}
+
+Future<List<Object>> f1() async {}
+List<Object> f2() => [2];
+Future<Object> f3() async {}
+Future<X> foo() async {}
+Future<void> main() async {}
diff --git a/pkg/front_end/testcases/general/bug33206.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/bug33206.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d229418
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug33206.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+import 'dart:async';
+
+Future<List<Object>> f1() async {}
+Future<Object> f3() async {}
+Future<X> foo() async {}
+Future<void> main() async {}
+List<Object> f2() => [2];
+
+class X {
+ X(this.x, this.y);
+ final x;
+ final y;
+ toString() => "X($x, $y)";
+}
+
+class Y {
+ f(_) {}
+}
diff --git a/pkg/front_end/testcases/general/bug33298.dart.textual_outline.expect b/pkg/front_end/testcases/general/bug33298.dart.textual_outline.expect
new file mode 100644
index 0000000..e2157d3
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug33298.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+class A {
+ String call(String s) => '$s$s';
+}
+
+class B<T> {
+ T call(T t) => t;
+}
+
+class C {
+ T call<T>(T t) => t;
+}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/bug33298.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/bug33298.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1bf1c4a
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug33298.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+class A {
+ String call(String s) => '$s$s';
+}
+
+class B<T> {
+ T call(T t) => t;
+}
+
+class C {
+ T call<T>(T t) => t;
+}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/bug34511.dart.textual_outline.expect b/pkg/front_end/testcases/general/bug34511.dart.textual_outline.expect
new file mode 100644
index 0000000..d85c73d
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug34511.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class A<X> {}
+
+class B<Z> extends Object with A<Z Function()> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/bug34511.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/bug34511.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d85c73d
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug34511.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+class A<X> {}
+
+class B<Z> extends Object with A<Z Function()> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/bug35470.dart.textual_outline.expect b/pkg/front_end/testcases/general/bug35470.dart.textual_outline.expect
new file mode 100644
index 0000000..880e7ff
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug35470.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+class A<X> {
+ foo<Y extends X>() {}
+}
+
+class B extends A<dynamic> {}
+
+bar(B b) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/bug35470.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/bug35470.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ee614fb
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug35470.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+bar(B b) {}
+
+class A<X> {
+ foo<Y extends X>() {}
+}
+
+class B extends A<dynamic> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/bug37476.dart.textual_outline.expect b/pkg/front_end/testcases/general/bug37476.dart.textual_outline.expect
new file mode 100644
index 0000000..5f90d7d
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug37476.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class A<T extends num> {
+ void Function<S extends T>(S x) foo() {}
+}
+
+class B<T extends num> {
+ void Function(T x) foo() {}
+}
+
+A<num> a = new A<int>();
+B<num> b = new B<int>();
+main() {}
diff --git a/pkg/front_end/testcases/general/bug37476.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/bug37476.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8cbb59f
--- /dev/null
+++ b/pkg/front_end/testcases/general/bug37476.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+A<num> a = new A<int>();
+B<num> b = new B<int>();
+
+class A<T extends num> {
+ void Function<S extends T>(S x) foo() {}
+}
+
+class B<T extends num> {
+ void Function(T x) foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/call.dart.textual_outline.expect b/pkg/front_end/testcases/general/call.dart.textual_outline.expect
new file mode 100644
index 0000000..f9a3aa0
--- /dev/null
+++ b/pkg/front_end/testcases/general/call.dart.textual_outline.expect
@@ -0,0 +1,36 @@
+class Callable {
+ call(x) {}
+}
+
+class CallableGetter {
+ get call => new Callable();
+}
+
+main() {}
+var closure = (x) => x;
+var int1 = closure(1);
+var int2 = closure.call(1);
+var int3 = closure.call.call(1);
+var int4 = closure.call.call.call(1);
+var callable = new Callable();
+var string1 = callable(1);
+var string2 = callable.call(1);
+var string3 = callable.call.call(1);
+var string4 = callable.call.call.call(1);
+var callableGetter = new CallableGetter();
+var string5 = callableGetter(1);
+var string6 = callableGetter.call(1);
+var string7 = callableGetter.call.call(1);
+var string8 = callableGetter.call.call.call(1);
+var nothing1 = closure();
+var nothing2 = closure.call();
+var nothing3 = closure.call.call();
+var nothing4 = closure.call.call.call();
+var nothing5 = callable();
+var nothing6 = callable.call();
+var nothing7 = callable.call.call();
+var nothing8 = callable.call.call.call();
+var nothing9 = callableGetter();
+var nothing10 = callableGetter.call();
+var nothing11 = callableGetter.call.call();
+var nothing12 = callableGetter.call.call.call();
diff --git a/pkg/front_end/testcases/general/call.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/call.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2eca437
--- /dev/null
+++ b/pkg/front_end/testcases/general/call.dart.textual_outline_modelled.expect
@@ -0,0 +1,36 @@
+class Callable {
+ call(x) {}
+}
+
+class CallableGetter {
+ get call => new Callable();
+}
+
+main() {}
+var callable = new Callable();
+var callableGetter = new CallableGetter();
+var closure = (x) => x;
+var int1 = closure(1);
+var int2 = closure.call(1);
+var int3 = closure.call.call(1);
+var int4 = closure.call.call.call(1);
+var nothing1 = closure();
+var nothing10 = callableGetter.call();
+var nothing11 = callableGetter.call.call();
+var nothing12 = callableGetter.call.call.call();
+var nothing2 = closure.call();
+var nothing3 = closure.call.call();
+var nothing4 = closure.call.call.call();
+var nothing5 = callable();
+var nothing6 = callable.call();
+var nothing7 = callable.call.call();
+var nothing8 = callable.call.call.call();
+var nothing9 = callableGetter();
+var string1 = callable(1);
+var string2 = callable.call(1);
+var string3 = callable.call.call(1);
+var string4 = callable.call.call.call(1);
+var string5 = callableGetter(1);
+var string6 = callableGetter.call(1);
+var string7 = callableGetter.call.call(1);
+var string8 = callableGetter.call.call.call(1);
diff --git a/pkg/front_end/testcases/general/candidate_found.dart.textual_outline.expect b/pkg/front_end/testcases/general/candidate_found.dart.textual_outline.expect
new file mode 100644
index 0000000..59e6dfd
--- /dev/null
+++ b/pkg/front_end/testcases/general/candidate_found.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class Fisk {
+ Fisk(int x) {}
+ Fisk.named(int x) {}
+ void method(int x) {}
+ static void staticMethod(int x) {}
+}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/candidate_found.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/candidate_found.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..49525b6
--- /dev/null
+++ b/pkg/front_end/testcases/general/candidate_found.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class Fisk {
+ Fisk(int x) {}
+ Fisk.named(int x) {}
+ static void staticMethod(int x) {}
+ void method(int x) {}
+}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/cascade.dart.textual_outline.expect b/pkg/front_end/testcases/general/cascade.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/cascade.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/cascade.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/cascade.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/cascade.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/casts.dart.textual_outline.expect b/pkg/front_end/testcases/general/casts.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/casts.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/casts.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/casts.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/casts.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/check_deferred_allocation.dart.textual_outline.expect b/pkg/front_end/testcases/general/check_deferred_allocation.dart.textual_outline.expect
new file mode 100644
index 0000000..05d29b6
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_allocation.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/check_deferred_allocation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/check_deferred_allocation.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..05d29b6
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_allocation.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/check_deferred_as_check.dart.textual_outline.expect b/pkg/front_end/testcases/general/check_deferred_as_check.dart.textual_outline.expect
new file mode 100644
index 0000000..9a994a0
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_as_check.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test(x) {}
diff --git a/pkg/front_end/testcases/general/check_deferred_as_check.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/check_deferred_as_check.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9a994a0
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_as_check.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test(x) {}
diff --git a/pkg/front_end/testcases/general/check_deferred_before_args.dart.textual_outline.expect b/pkg/front_end/testcases/general/check_deferred_before_args.dart.textual_outline.expect
new file mode 100644
index 0000000..4ddbfed
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_before_args.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
+m2() => 1;
diff --git a/pkg/front_end/testcases/general/check_deferred_before_args.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/check_deferred_before_args.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2e73aad
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_before_args.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import 'deferred_lib.dart' deferred as lib;
+
+m2() => 1;
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/check_deferred_before_args2.dart.textual_outline.expect b/pkg/front_end/testcases/general/check_deferred_before_args2.dart.textual_outline.expect
new file mode 100644
index 0000000..72746c9
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_before_args2.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() async {}
diff --git a/pkg/front_end/testcases/general/check_deferred_before_args2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/check_deferred_before_args2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..72746c9
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_before_args2.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() async {}
diff --git a/pkg/front_end/testcases/general/check_deferred_before_call.dart.textual_outline.expect b/pkg/front_end/testcases/general/check_deferred_before_call.dart.textual_outline.expect
new file mode 100644
index 0000000..05d29b6
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_before_call.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/check_deferred_before_call.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/check_deferred_before_call.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..05d29b6
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_before_call.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/check_deferred_before_write.dart.textual_outline.expect b/pkg/front_end/testcases/general/check_deferred_before_write.dart.textual_outline.expect
new file mode 100644
index 0000000..05d29b6
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_before_write.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/check_deferred_before_write.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/check_deferred_before_write.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..05d29b6
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_before_write.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/check_deferred_is_check.dart.textual_outline.expect b/pkg/front_end/testcases/general/check_deferred_is_check.dart.textual_outline.expect
new file mode 100644
index 0000000..9a994a0
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_is_check.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test(x) {}
diff --git a/pkg/front_end/testcases/general/check_deferred_is_check.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/check_deferred_is_check.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9a994a0
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_is_check.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test(x) {}
diff --git a/pkg/front_end/testcases/general/check_deferred_read.dart.textual_outline.expect b/pkg/front_end/testcases/general/check_deferred_read.dart.textual_outline.expect
new file mode 100644
index 0000000..05d29b6
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_read.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/check_deferred_read.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/check_deferred_read.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..05d29b6
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_read.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/check_deferred_read_static_field.dart.textual_outline.expect b/pkg/front_end/testcases/general/check_deferred_read_static_field.dart.textual_outline.expect
new file mode 100644
index 0000000..05d29b6
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_read_static_field.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/check_deferred_read_static_field.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/check_deferred_read_static_field.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..05d29b6
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_read_static_field.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/check_deferred_read_type.dart.textual_outline.expect b/pkg/front_end/testcases/general/check_deferred_read_type.dart.textual_outline.expect
new file mode 100644
index 0000000..05d29b6
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_read_type.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/check_deferred_read_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/check_deferred_read_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..05d29b6
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_read_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/check_deferred_static_method_call.dart.textual_outline.expect b/pkg/front_end/testcases/general/check_deferred_static_method_call.dart.textual_outline.expect
new file mode 100644
index 0000000..05d29b6
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_static_method_call.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/check_deferred_static_method_call.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/check_deferred_static_method_call.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..05d29b6
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_static_method_call.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/check_deferred_type_declaration.dart.textual_outline.expect b/pkg/front_end/testcases/general/check_deferred_type_declaration.dart.textual_outline.expect
new file mode 100644
index 0000000..b8fbde2
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_type_declaration.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() => test();
+test() {}
diff --git a/pkg/front_end/testcases/general/check_deferred_type_declaration.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/check_deferred_type_declaration.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b8fbde2
--- /dev/null
+++ b/pkg/front_end/testcases/general/check_deferred_type_declaration.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() => test();
+test() {}
diff --git a/pkg/front_end/testcases/general/circularity-via-initializing-formal.dart.textual_outline.expect b/pkg/front_end/testcases/general/circularity-via-initializing-formal.dart.textual_outline.expect
new file mode 100644
index 0000000..9252577
--- /dev/null
+++ b/pkg/front_end/testcases/general/circularity-via-initializing-formal.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+var x = new C._circular(null);
+
+class C {
+ var f = new C._circular(null);
+ C._circular(this.f);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/circularity-via-initializing-formal.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/circularity-via-initializing-formal.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9e8e7de
--- /dev/null
+++ b/pkg/front_end/testcases/general/circularity-via-initializing-formal.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class C {
+ C._circular(this.f);
+ var f = new C._circular(null);
+}
+
+main() {}
+var x = new C._circular(null);
diff --git a/pkg/front_end/testcases/general/classes.dart.textual_outline.expect b/pkg/front_end/testcases/general/classes.dart.textual_outline.expect
new file mode 100644
index 0000000..db9b2ee
--- /dev/null
+++ b/pkg/front_end/testcases/general/classes.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+class A {
+ final int x;
+ final int y;
+ A(this.y) : x = 42;
+ method() {}
+}
+
+class B extends A {
+ B(x) : super(x);
+ method() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/classes.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/classes.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6b4696f
--- /dev/null
+++ b/pkg/front_end/testcases/general/classes.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+class A {
+ A(this.y) : x = 42;
+ final int x;
+ final int y;
+ method() {}
+}
+
+class B extends A {
+ B(x) : super(x);
+ method() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/clone_function_type.dart.textual_outline.expect b/pkg/front_end/testcases/general/clone_function_type.dart.textual_outline.expect
new file mode 100644
index 0000000..767a6f0
--- /dev/null
+++ b/pkg/front_end/testcases/general/clone_function_type.dart.textual_outline.expect
@@ -0,0 +1,146 @@
+class Am1<X, Y> {
+}
+class Bm1<Z> extends Object with Am1<Function(int), Z> {
+}
+class Cm1<Z> extends Object with Am1<Function(int x), Z> {
+}
+class Dm1<Z> extends Object with Am1<int Function(), Z> {
+}
+class Em1<Z> extends Object with Am1<Function(), Z> {
+}
+class Fm1<Z> extends Object with Am1<Function({int}), Z> {
+}
+class Gm1<Z> extends Object with Am1<Function({int x}), Z> {
+}
+class Hm1<Z> extends Object with Am1<Function([int]), Z> {
+}
+class Im1<Z> extends Object with Am1<Function([int x]), Z> {
+}
+class Jm1<Z> extends Object with Am1<Function, Z> {
+}
+class Km1<Z> extends Object with Am1<Function(Function Function), Z> {
+}
+class Lm1<Z> extends Object with Am1<Function(Function Function() Function) Function(), Z> {
+}
+class Mm1<Z> = Object with Am1<Function(int), Z>; class Nm1<Z> = Object with Am1<Function(int x), Z>; class Om1<Z> = Object with Am1<int Function(), Z>; class Pm1<Z> = Object with Am1<Function(), Z>; class Qm1<Z> = Object with Am1<Function({int}), Z>; class Rm1<Z> = Object with Am1<Function({int x}), Z>; class Sm1<Z> = Object with Am1<Function([int]), Z>; class Tm1<Z> = Object with Am1<Function([int x]), Z>; class Um1<Z> = Object with Am1<Function, Z>; class Vm1<Z> = Object with Am1<Function(Function Function), Z>; class Wm1<Z> = Object with Am1<Function(Function Function() Function) Function(), Z>;
+class Am2<X extends Function(), Y> {
+}
+class Bm2<Z> extends Object with Am2<Function(int), Z> {
+}
+class Cm2<Z> extends Object with Am2<Function(int x), Z> {
+}
+class Dm2<Z> extends Object with Am2<int Function(), Z> {
+}
+class Em2<Z> extends Object with Am2<Function(), Z> {
+}
+class Fm2<Z> extends Object with Am2<Function({int}), Z> {
+}
+class Gm2<Z> extends Object with Am2<Function({int x}), Z> {
+}
+class Hm2<Z> extends Object with Am2<Function([int]), Z> {
+}
+class Im2<Z> extends Object with Am2<Function([int x]), Z> {
+}
+class Jm2<Z> extends Object with Am2<Function, Z> {
+}
+class Km2<Z> extends Object with Am2<Function(Function Function), Z> {
+}
+class Lm2<Z> extends Object with Am2<Function(Function Function() Function) Function(), Z> {
+}
+class Mm2<Z> = Object with Am2<Function(int), Z>; class Nm2<Z> = Object with Am2<Function(int x), Z>; class Om2<Z> = Object with Am2<int Function(), Z>; class Pm2<Z> = Object with Am2<Function(), Z>; class Qm2<Z> = Object with Am2<Function({int}), Z>; class Rm2<Z> = Object with Am2<Function({int x}), Z>; class Sm2<Z> = Object with Am2<Function([int]), Z>; class Tm2<Z> = Object with Am2<Function([int x]), Z>; class Um2<Z> = Object with Am2<Function, Z>; class Vm2<Z> = Object with Am2<Function(Function Function), Z>; class Wm2<Z> = Object with Am2<Function(Function Function() Function) Function(), Z>;
+typedef TdB = Function(int);
+typedef TdC = Function(int x);
+typedef TdD = int Function();
+typedef TdE = Function();
+typedef TdF = Function({int});
+typedef TdG = Function({int x});
+typedef TdH = Function([int]);
+typedef TdI = Function([int x]);
+typedef TdJ = Function(Function Function);
+typedef TdK = Function(Function Function() Function) Function();
+class Am3<L, Y> {
+}
+class Bm3<Z> extends Object with Am3<TdB, Z> {
+}
+class Cm3<Z> extends Object with Am3<TdC, Z> {
+}
+class Dm3<Z> extends Object with Am3<TdD, Z> {
+}
+class Em3<Z> extends Object with Am3<TdE, Z> {
+}
+class Fm3<Z> extends Object with Am3<TdF, Z> {
+}
+class Gm3<Z> extends Object with Am3<TdG, Z> {
+}
+class Hm3<Z> extends Object with Am3<TdH, Z> {
+}
+class Im3<Z> extends Object with Am3<TdI, Z> {
+}
+class Jm3<Z> extends Object with Am3<TdJ, Z> {
+}
+class Km3<Z> extends Object with Am3<TdK, Z> {
+}
+class Af1<X extends Function(int)> {
+ factory Af1.foo() => null;
+}
+class Bf1<X extends Function(int x)> {
+ factory Bf1.foo() => null;
+}
+class Cf1<X extends int Function()> {
+ factory Cf1.foo() => null;
+}
+class Df1<X extends Function()> {
+ factory Df1.foo() => null;
+}
+class Ef1<X extends Function({int})> {
+ factory Ef1.foo() => null;
+}
+class Ff1<X extends Function({int x})> {
+ factory Ff1.foo() => null;
+}
+class Gf1<X extends Function([int])> {
+ factory Gf1.foo() => null;
+}
+class Hf1<X extends Function([int x])> {
+ factory Hf1.foo() => null;
+}
+class If1<X extends Function> {
+ factory If1.foo() => null;
+}
+class Jf1<X extends Function(Function Function)> {
+ factory Jf1.foo() => null;
+}
+class Kf1<X extends Function(Function Function() Function) Function()> {
+ factory Kf1.foo() => null;
+}
+class Bf2<X extends TdB> {
+ factory Bf2.foo() => null;
+}
+class Cf2<X extends TdC> {
+ factory Cf2.foo() => null;
+}
+class Df2<X extends TdD> {
+ factory Df2.foo() => null;
+}
+class Ef2<X extends TdE> {
+ factory Ef2.foo() => null;
+}
+class Ff2<X extends TdF> {
+ factory Ff2.foo() => null;
+}
+class Gf2<X extends TdG> {
+ factory Gf2.foo() => null;
+}
+class Hf2<X extends TdH> {
+ factory Hf2.foo() => null;
+}
+class If2<X extends TdI> {
+ factory If2.foo() => null;
+}
+class Jf2<X extends TdJ> {
+ factory Jf2.foo() => null;
+}
+class Kf2<X extends TdK> {
+ factory Kf2.foo() => null;
+}
+main() { }
diff --git a/pkg/front_end/testcases/general/closure.dart.textual_outline.expect b/pkg/front_end/testcases/general/closure.dart.textual_outline.expect
new file mode 100644
index 0000000..544a9e7
--- /dev/null
+++ b/pkg/front_end/testcases/general/closure.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+class Foo {
+ var _field = new Bar();
+}
+
+class Bar {}
+
+useCallback(callback) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/closure.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/closure.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2f6023d
--- /dev/null
+++ b/pkg/front_end/testcases/general/closure.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+class Bar {}
+
+class Foo {
+ var _field = new Bar();
+}
+
+main() {}
+useCallback(callback) {}
diff --git a/pkg/front_end/testcases/general/co19_language_metadata_syntax_t04.dart.textual_outline.expect b/pkg/front_end/testcases/general/co19_language_metadata_syntax_t04.dart.textual_outline.expect
new file mode 100644
index 0000000..896c9f0
--- /dev/null
+++ b/pkg/front_end/testcases/general/co19_language_metadata_syntax_t04.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class A {
+ const A();
+}
+
+A() {}
+
+class B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/co19_language_metadata_syntax_t04.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/co19_language_metadata_syntax_t04.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c112c59
--- /dev/null
+++ b/pkg/front_end/testcases/general/co19_language_metadata_syntax_t04.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+A() {}
+
+class A {
+ const A();
+}
+
+class B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/complex_class_hierarchy.dart.textual_outline.expect b/pkg/front_end/testcases/general/complex_class_hierarchy.dart.textual_outline.expect
new file mode 100644
index 0000000..adeaf17
--- /dev/null
+++ b/pkg/front_end/testcases/general/complex_class_hierarchy.dart.textual_outline.expect
@@ -0,0 +1,43 @@
+main() {}
+
+class A {}
+
+class B extends A {}
+
+class C extends B {}
+
+class D extends C {}
+
+class G<T extends A> {}
+
+class GB extends G<B> {}
+
+class GC extends G<C> {}
+
+class GD extends G<D> {}
+
+class X implements A {}
+
+class Y extends X {}
+
+class Z implements Y {}
+
+class W implements Z {}
+
+class GX implements G<A> {}
+
+class GY extends X implements GB {}
+
+class GZ implements Y, GC {}
+
+class GW implements Z, GD {}
+
+class GU extends GW {}
+
+class GV extends GU implements GW {}
+
+class ARO<S> {}
+
+class ARQ<T> extends Object implements ARO<T> {}
+
+class ARN extends ARQ<A> {}
diff --git a/pkg/front_end/testcases/general/complex_class_hierarchy.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/complex_class_hierarchy.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ca66b2f
--- /dev/null
+++ b/pkg/front_end/testcases/general/complex_class_hierarchy.dart.textual_outline_modelled.expect
@@ -0,0 +1,43 @@
+class A {}
+
+class ARN extends ARQ<A> {}
+
+class ARO<S> {}
+
+class ARQ<T> extends Object implements ARO<T> {}
+
+class B extends A {}
+
+class C extends B {}
+
+class D extends C {}
+
+class G<T extends A> {}
+
+class GB extends G<B> {}
+
+class GC extends G<C> {}
+
+class GD extends G<D> {}
+
+class GU extends GW {}
+
+class GV extends GU implements GW {}
+
+class GW implements Z, GD {}
+
+class GX implements G<A> {}
+
+class GY extends X implements GB {}
+
+class GZ implements Y, GC {}
+
+class W implements Z {}
+
+class X implements A {}
+
+class Y extends X {}
+
+class Z implements Y {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/compound_binary_implicit_as.dart.textual_outline.expect b/pkg/front_end/testcases/general/compound_binary_implicit_as.dart.textual_outline.expect
new file mode 100644
index 0000000..19f543a
--- /dev/null
+++ b/pkg/front_end/testcases/general/compound_binary_implicit_as.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class A {}
+
+class B extends A {
+ A operator +(B b) => new C();
+}
+
+class C extends A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/compound_binary_implicit_as.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/compound_binary_implicit_as.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..19f543a
--- /dev/null
+++ b/pkg/front_end/testcases/general/compound_binary_implicit_as.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class A {}
+
+class B extends A {
+ A operator +(B b) => new C();
+}
+
+class C extends A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/const_redirect_to_nonconst.dart.textual_outline.expect b/pkg/front_end/testcases/general/const_redirect_to_nonconst.dart.textual_outline.expect
new file mode 100644
index 0000000..8d81665e
--- /dev/null
+++ b/pkg/front_end/testcases/general/const_redirect_to_nonconst.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class A {
+ const A() : this.bad();
+ A.bad() {}
+}
+
+class B extends A {
+ const B() : super.bad();
+}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/const_redirect_to_nonconst.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/const_redirect_to_nonconst.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bee691e
--- /dev/null
+++ b/pkg/front_end/testcases/general/const_redirect_to_nonconst.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+class A {
+ A.bad() {}
+ const A() : this.bad();
+}
+
+class B extends A {
+ const B() : super.bad();
+}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/constant_truncate.dart.textual_outline.expect b/pkg/front_end/testcases/general/constant_truncate.dart.textual_outline.expect
new file mode 100644
index 0000000..44d49e8
--- /dev/null
+++ b/pkg/front_end/testcases/general/constant_truncate.dart.textual_outline.expect
@@ -0,0 +1,40 @@
+const a0 = 0 ~/ 0;
+const a1 = 0.0 ~/ 0;
+const a2 = -0.0 ~/ 0;
+const a3 = double.nan ~/ 0;
+const a4 = double.infinity ~/ 0;
+const a5 = double.negativeInfinity ~/ 0;
+const b0 = 0 ~/ 0.0;
+const b1 = 0.0 ~/ 0.0;
+const b2 = -0.0 ~/ 0.0;
+const b3 = double.nan ~/ 0.0;
+const b4 = double.infinity ~/ 0.0;
+const b5 = double.negativeInfinity ~/ 0.0;
+const c0 = 0 ~/ -0.0;
+const c1 = 0.0 ~/ -0.0;
+const c2 = -0.0 ~/ -0.0;
+const c3 = double.nan ~/ -0.0;
+const c4 = double.infinity ~/ -0.0;
+const c5 = double.negativeInfinity ~/ -0.0;
+const d0 = 0 ~/ double.nan;
+const d1 = 0.0 ~/ double.nan;
+const d2 = -0.0 ~/ double.nan;
+const d3 = double.nan ~/ double.nan;
+const d4 = double.infinity ~/ double.nan;
+const d5 = double.negativeInfinity ~/ double.nan;
+const e0 = 0 ~/ double.infinity;
+const e1 = 0.0 ~/ double.infinity;
+const e2 = -0.0 ~/ double.infinity;
+const e3 = double.nan ~/ double.infinity;
+const e4 = double.infinity ~/ double.infinity;
+const e5 = double.negativeInfinity ~/ double.infinity;
+const f0 = 0 ~/ double.negativeInfinity;
+const f1 = 0.0 ~/ double.negativeInfinity;
+const f2 = -0.0 ~/ double.negativeInfinity;
+const f3 = double.nan ~/ double.negativeInfinity;
+const f4 = double.infinity ~/ double.negativeInfinity;
+const f5 = double.negativeInfinity ~/ double.negativeInfinity;
+main() {}
+void test(num a, num b, num Function() f) {}
+void expect(expected, actual) {}
+void throws(num Function() f) {}
diff --git a/pkg/front_end/testcases/general/constant_truncate.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/constant_truncate.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4eeedfa
--- /dev/null
+++ b/pkg/front_end/testcases/general/constant_truncate.dart.textual_outline_modelled.expect
@@ -0,0 +1,40 @@
+const a0 = 0 ~/ 0;
+const a1 = 0.0 ~/ 0;
+const a2 = -0.0 ~/ 0;
+const a3 = double.nan ~/ 0;
+const a4 = double.infinity ~/ 0;
+const a5 = double.negativeInfinity ~/ 0;
+const b0 = 0 ~/ 0.0;
+const b1 = 0.0 ~/ 0.0;
+const b2 = -0.0 ~/ 0.0;
+const b3 = double.nan ~/ 0.0;
+const b4 = double.infinity ~/ 0.0;
+const b5 = double.negativeInfinity ~/ 0.0;
+const c0 = 0 ~/ -0.0;
+const c1 = 0.0 ~/ -0.0;
+const c2 = -0.0 ~/ -0.0;
+const c3 = double.nan ~/ -0.0;
+const c4 = double.infinity ~/ -0.0;
+const c5 = double.negativeInfinity ~/ -0.0;
+const d0 = 0 ~/ double.nan;
+const d1 = 0.0 ~/ double.nan;
+const d2 = -0.0 ~/ double.nan;
+const d3 = double.nan ~/ double.nan;
+const d4 = double.infinity ~/ double.nan;
+const d5 = double.negativeInfinity ~/ double.nan;
+const e0 = 0 ~/ double.infinity;
+const e1 = 0.0 ~/ double.infinity;
+const e2 = -0.0 ~/ double.infinity;
+const e3 = double.nan ~/ double.infinity;
+const e4 = double.infinity ~/ double.infinity;
+const e5 = double.negativeInfinity ~/ double.infinity;
+const f0 = 0 ~/ double.negativeInfinity;
+const f1 = 0.0 ~/ double.negativeInfinity;
+const f2 = -0.0 ~/ double.negativeInfinity;
+const f3 = double.nan ~/ double.negativeInfinity;
+const f4 = double.infinity ~/ double.negativeInfinity;
+const f5 = double.negativeInfinity ~/ double.negativeInfinity;
+main() {}
+void expect(expected, actual) {}
+void test(num a, num b, num Function() f) {}
+void throws(num Function() f) {}
diff --git a/pkg/front_end/testcases/general/constructor_const_inference.dart.textual_outline.expect b/pkg/front_end/testcases/general/constructor_const_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..f6ab576
--- /dev/null
+++ b/pkg/front_end/testcases/general/constructor_const_inference.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+class _Y<T> {
+ const _Y();
+}
+
+class A<T> {
+ _Y<T> x;
+ A(this.x);
+}
+
+class B<T> extends A<T> {
+ B() : super(const _Y());
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/constructor_const_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/constructor_const_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6b4aec7
--- /dev/null
+++ b/pkg/front_end/testcases/general/constructor_const_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+class A<T> {
+ A(this.x);
+ _Y<T> x;
+}
+
+class B<T> extends A<T> {
+ B() : super(const _Y());
+}
+
+class _Y<T> {
+ const _Y();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/constructor_cycle.dart.textual_outline.expect b/pkg/front_end/testcases/general/constructor_cycle.dart.textual_outline.expect
new file mode 100644
index 0000000..4471e83
--- /dev/null
+++ b/pkg/front_end/testcases/general/constructor_cycle.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+class A {
+ A.foo() : this.bar();
+ A.bar() : this.foo();
+ A.baz() : this.foo();
+ A() : this();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/constructor_cycle.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/constructor_cycle.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..051f9f7
--- /dev/null
+++ b/pkg/front_end/testcases/general/constructor_cycle.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+class A {
+ A() : this();
+ A.bar() : this.foo();
+ A.baz() : this.foo();
+ A.foo() : this.bar();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/constructor_function_types.dart.textual_outline.expect b/pkg/front_end/testcases/general/constructor_function_types.dart.textual_outline.expect
new file mode 100644
index 0000000..52ecd80
--- /dev/null
+++ b/pkg/front_end/testcases/general/constructor_function_types.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+class A {
+ A();
+}
+
+class B {
+ B(int x, double y, String s);
+}
+
+class C<T> {
+ C();
+}
+
+class D<T, S> {
+ D(T x, S y);
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/constructor_function_types.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/constructor_function_types.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..52ecd80
--- /dev/null
+++ b/pkg/front_end/testcases/general/constructor_function_types.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+class A {
+ A();
+}
+
+class B {
+ B(int x, double y, String s);
+}
+
+class C<T> {
+ C();
+}
+
+class D<T, S> {
+ D(T x, S y);
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/constructor_initializer_invalid.dart.textual_outline.expect b/pkg/front_end/testcases/general/constructor_initializer_invalid.dart.textual_outline.expect
new file mode 100644
index 0000000..2516417
--- /dev/null
+++ b/pkg/front_end/testcases/general/constructor_initializer_invalid.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+class C1 {
+ int f;
+ C1() : =;
+}
+class C2 {
+ int f;
+ C2() : f=;
+}
+class C3 {
+ int f;
+ C3() : =f++;
+}
+main() { }
diff --git a/pkg/front_end/testcases/general/continue_inference_after_error.dart.textual_outline.expect b/pkg/front_end/testcases/general/continue_inference_after_error.dart.textual_outline.expect
new file mode 100644
index 0000000..419aa23
--- /dev/null
+++ b/pkg/front_end/testcases/general/continue_inference_after_error.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+import "continue_inference_after_error_lib.dart" as lib;
+
+class C {}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/continue_inference_after_error.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/continue_inference_after_error.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2384d20
--- /dev/null
+++ b/pkg/front_end/testcases/general/continue_inference_after_error.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+import "continue_inference_after_error_lib.dart" as lib;
+
+class C {}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/control_flow_collection.dart.textual_outline.expect b/pkg/front_end/testcases/general/control_flow_collection.dart.textual_outline.expect
new file mode 100644
index 0000000..f4795c0
--- /dev/null
+++ b/pkg/front_end/testcases/general/control_flow_collection.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+main() {}
+oracle() => true;
diff --git a/pkg/front_end/testcases/general/control_flow_collection.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/control_flow_collection.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f4795c0
--- /dev/null
+++ b/pkg/front_end/testcases/general/control_flow_collection.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+main() {}
+oracle() => true;
diff --git a/pkg/front_end/testcases/general/control_flow_collection_inference.dart.textual_outline.expect b/pkg/front_end/testcases/general/control_flow_collection_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..e011ec5
--- /dev/null
+++ b/pkg/front_end/testcases/general/control_flow_collection_inference.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+oracle<T>([T t]) => true;
+testIfElement(dynamic dynVar, List<int> listInt, List<double> listDouble,
+ Map<String, int> mapToInt, Map<String, double> mapToDouble) {}
+testIfElementErrors(Map<int, int> map) {}
+testForElement(
+ dynamic dynVar,
+ List<int> listInt,
+ List<double> listDouble,
+ int index,
+ Map<String, int> mapStringInt,
+ Map<String, double> mapStringDouble) {}
+testForElementErrors(Map<int, int> map, List<int> list) async {}
+testForElementErrorsNotAsync(Stream<int> stream) {}
+
+class A {}
+
+class B extends A {
+ int get foo => 42;
+}
+
+testPromotion(A a) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/control_flow_collection_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/control_flow_collection_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8a8e5b1
--- /dev/null
+++ b/pkg/front_end/testcases/general/control_flow_collection_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+class A {}
+
+class B extends A {
+ int get foo => 42;
+}
+
+main() {}
+oracle<T>([T t]) => true;
+testForElement(
+ dynamic dynVar,
+ List<int> listInt,
+ List<double> listDouble,
+ int index,
+ Map<String, int> mapStringInt,
+ Map<String, double> mapStringDouble) {}
+testForElementErrors(Map<int, int> map, List<int> list) async {}
+testForElementErrorsNotAsync(Stream<int> stream) {}
+testIfElement(dynamic dynVar, List<int> listInt, List<double> listDouble,
+ Map<String, int> mapToInt, Map<String, double> mapToDouble) {}
+testIfElementErrors(Map<int, int> map) {}
+testPromotion(A a) {}
diff --git a/pkg/front_end/testcases/general/covariant_equals.dart.textual_outline.expect b/pkg/front_end/testcases/general/covariant_equals.dart.textual_outline.expect
new file mode 100644
index 0000000..cfe571a
--- /dev/null
+++ b/pkg/front_end/testcases/general/covariant_equals.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+class A {
+ bool operator ==(covariant A other) => true;
+}
+
+class B extends A {
+ bool operator ==(other) => true;
+}
+
+class C<T> {
+ bool operator ==(covariant C<T> other) => true;
+}
+
+class D extends C<int> {}
+
+main() {}
+test(A a, B b, C c_dynamic, C<int> c_int, C<String> c_string, D d) {}
diff --git a/pkg/front_end/testcases/general/covariant_equals.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/covariant_equals.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cfe571a
--- /dev/null
+++ b/pkg/front_end/testcases/general/covariant_equals.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+class A {
+ bool operator ==(covariant A other) => true;
+}
+
+class B extends A {
+ bool operator ==(other) => true;
+}
+
+class C<T> {
+ bool operator ==(covariant C<T> other) => true;
+}
+
+class D extends C<int> {}
+
+main() {}
+test(A a, B b, C c_dynamic, C<int> c_int, C<String> c_string, D d) {}
diff --git a/pkg/front_end/testcases/general/covariant_generic.dart.textual_outline.expect b/pkg/front_end/testcases/general/covariant_generic.dart.textual_outline.expect
new file mode 100644
index 0000000..4fe7336
--- /dev/null
+++ b/pkg/front_end/testcases/general/covariant_generic.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+typedef void Callback<T>(T x);
+
+class Foo<T> {
+ final T finalField;
+ final Callback<T> callbackField;
+ T mutableField;
+ Callback<T> mutableCallbackField;
+ Foo(this.finalField, this.callbackField);
+ void method(T x) {}
+ set setter(T x) {}
+ void withCallback(Callback<T> callback) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/covariant_generic.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/covariant_generic.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..40004ba
--- /dev/null
+++ b/pkg/front_end/testcases/general/covariant_generic.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+class Foo<T> {
+ Callback<T> mutableCallbackField;
+ Foo(this.finalField, this.callbackField);
+ T mutableField;
+ final Callback<T> callbackField;
+ final T finalField;
+ set setter(T x) {}
+ void method(T x) {}
+ void withCallback(Callback<T> callback) {}
+}
+
+main() {}
+typedef void Callback<T>(T x);
diff --git a/pkg/front_end/testcases/general/covariant_parameter_in_superclass_of_mixin_application.dart.textual_outline.expect b/pkg/front_end/testcases/general/covariant_parameter_in_superclass_of_mixin_application.dart.textual_outline.expect
new file mode 100644
index 0000000..914deb7
--- /dev/null
+++ b/pkg/front_end/testcases/general/covariant_parameter_in_superclass_of_mixin_application.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+class A {
+ void foo(covariant num x) {}
+}
+
+class B {
+ void foo(num x) {}
+}
+
+class C {
+ void foo(num x) {}
+}
+
+class D extends A with B implements C {
+ void foo(int x) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/covariant_parameter_in_superclass_of_mixin_application.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/covariant_parameter_in_superclass_of_mixin_application.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..914deb7
--- /dev/null
+++ b/pkg/front_end/testcases/general/covariant_parameter_in_superclass_of_mixin_application.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+class A {
+ void foo(covariant num x) {}
+}
+
+class B {
+ void foo(num x) {}
+}
+
+class C {
+ void foo(num x) {}
+}
+
+class D extends A with B implements C {
+ void foo(int x) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/cycles.dart.textual_outline.expect b/pkg/front_end/testcases/general/cycles.dart.textual_outline.expect
new file mode 100644
index 0000000..362437f
--- /dev/null
+++ b/pkg/front_end/testcases/general/cycles.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class A implements C {}
+
+class B extends A {}
+
+class C extends B implements D {}
+
+class D {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/cycles.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/cycles.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..362437f
--- /dev/null
+++ b/pkg/front_end/testcases/general/cycles.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class A implements C {}
+
+class B extends A {}
+
+class C extends B implements D {}
+
+class D {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/default_values.dart.textual_outline.expect b/pkg/front_end/testcases/general/default_values.dart.textual_outline.expect
new file mode 100644
index 0000000..c04eb61
--- /dev/null
+++ b/pkg/front_end/testcases/general/default_values.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+topLevel([a = 42]) => a;
+main() {}
diff --git a/pkg/front_end/testcases/general/default_values.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/default_values.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c95e3f3
--- /dev/null
+++ b/pkg/front_end/testcases/general/default_values.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+main() {}
+topLevel([a = 42]) => a;
diff --git a/pkg/front_end/testcases/general/deferred_type_annotation.dart.textual_outline.expect b/pkg/front_end/testcases/general/deferred_type_annotation.dart.textual_outline.expect
new file mode 100644
index 0000000..5139710
--- /dev/null
+++ b/pkg/front_end/testcases/general/deferred_type_annotation.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as d;
+
+bad(d.C x) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/deferred_type_annotation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/deferred_type_annotation.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5139710
--- /dev/null
+++ b/pkg/front_end/testcases/general/deferred_type_annotation.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as d;
+
+bad(d.C x) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/demote_closure_types.dart.textual_outline.expect b/pkg/front_end/testcases/general/demote_closure_types.dart.textual_outline.expect
new file mode 100644
index 0000000..fee39b9
--- /dev/null
+++ b/pkg/front_end/testcases/general/demote_closure_types.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+method<T>(T a, T b) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/demote_closure_types.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/demote_closure_types.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..caff637
--- /dev/null
+++ b/pkg/front_end/testcases/general/demote_closure_types.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+main() {}
+method<T>(T a, T b) {}
diff --git a/pkg/front_end/testcases/general/duplicated_bad_prefix.dart.textual_outline.expect b/pkg/front_end/testcases/general/duplicated_bad_prefix.dart.textual_outline.expect
new file mode 100644
index 0000000..17b7541
--- /dev/null
+++ b/pkg/front_end/testcases/general/duplicated_bad_prefix.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+import 'duplicated_bad_prefix_lib1.dart' as dupe;
+import 'duplicated_bad_prefix_lib2.dart' as dupe;
+
+class Dupe {}
+
+class Dupe {}
+
+class C {
+ Dupe.a b;
+ dupe.C d;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/duplicated_bad_prefix.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/duplicated_bad_prefix.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8169867
--- /dev/null
+++ b/pkg/front_end/testcases/general/duplicated_bad_prefix.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+import 'duplicated_bad_prefix_lib1.dart' as dupe;
+import 'duplicated_bad_prefix_lib2.dart' as dupe;
+
+class C {
+ Dupe.a b;
+ dupe.C d;
+}
+
+class Dupe {}
+
+class Dupe {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/duplicated_declarations.dart.textual_outline.expect b/pkg/front_end/testcases/general/duplicated_declarations.dart.textual_outline.expect
new file mode 100644
index 0000000..6e1f5b2
--- /dev/null
+++ b/pkg/front_end/testcases/general/duplicated_declarations.dart.textual_outline.expect
@@ -0,0 +1,33 @@
+part "duplicated_declarations_part.dart"; import 'duplicated_declarations_lib.dart' as Typedef; import 'duplicated_declarations_lib.dart' as Typedef;
+typedef Typedef = void Function();
+typedef Typedef = Object Function();
+import 'duplicated_declarations_lib.dart' as Typedef;
+typedef void OldTypedef();
+typedef Object OldTypedef();
+var field = "1st";
+var field = "2nd";
+main() { }
+main() { }
+foo() { }
+class C {
+ C(a);
+ C(a, b);
+ var field = "1st";
+ var field = "2nd";
+ m() { }
+ m() { }
+ static s() { }
+ static s() { }
+ static f() => s;
+}
+class Sub extends C {
+ Sub() : super(null);
+ m() => super.m();
+}
+class C {
+ C._();
+}
+enum Enum { Enum, a, a, b, }
+enum Enum { a, b, c, }
+enum AnotherEnum { a, b, c, _name, index, toString, values, }
+useAnotherEnum() { }
diff --git a/pkg/front_end/testcases/general/duplicated_field_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/general/duplicated_field_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..541f502
--- /dev/null
+++ b/pkg/front_end/testcases/general/duplicated_field_initializer.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class A {
+ int a;
+ int a;
+ A(this.a);
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/duplicated_field_initializer.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/duplicated_field_initializer.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1261a73
--- /dev/null
+++ b/pkg/front_end/testcases/general/duplicated_field_initializer.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class A {
+ A(this.a);
+ int a;
+ int a;
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/duplicated_named_args_3.dart.textual_outline.expect b/pkg/front_end/testcases/general/duplicated_named_args_3.dart.textual_outline.expect
new file mode 100644
index 0000000..0b2371b
--- /dev/null
+++ b/pkg/front_end/testcases/general/duplicated_named_args_3.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C {
+ static m({int a: 0}) {}
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/duplicated_named_args_3.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/duplicated_named_args_3.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..461825b
--- /dev/null
+++ b/pkg/front_end/testcases/general/duplicated_named_args_3.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C {
+ static m({int a: 0}) {}
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/general/dynamic_and_void.dart.textual_outline.expect b/pkg/front_end/testcases/general/dynamic_and_void.dart.textual_outline.expect
new file mode 100644
index 0000000..64c5d3e
--- /dev/null
+++ b/pkg/front_end/testcases/general/dynamic_and_void.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'dart:core' show int;
+
+dynamic testDynamic() => 0;
+void testVoid() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/dynamic_and_void.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/dynamic_and_void.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fd30a61
--- /dev/null
+++ b/pkg/front_end/testcases/general/dynamic_and_void.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import 'dart:core' show int;
+
+dynamic testDynamic() => 0;
+main() {}
+void testVoid() {}
diff --git a/pkg/front_end/testcases/general/error_locations/error_location_01.dart.textual_outline.expect b/pkg/front_end/testcases/general/error_locations/error_location_01.dart.textual_outline.expect
new file mode 100644
index 0000000..5332212
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_locations/error_location_01.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'error_location_01_lib1.dart';
+import 'error_location_01_lib2.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/error_locations/error_location_01.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/error_locations/error_location_01.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5332212
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_locations/error_location_01.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'error_location_01_lib1.dart';
+import 'error_location_01_lib2.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/error_locations/error_location_02.dart.textual_outline.expect b/pkg/front_end/testcases/general/error_locations/error_location_02.dart.textual_outline.expect
new file mode 100644
index 0000000..0bb920e
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_locations/error_location_02.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'error_location_02_lib1.dart';
+import 'error_location_02_lib2.dart';
+import 'error_location_02_lib3.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/error_locations/error_location_02.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/error_locations/error_location_02.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0bb920e
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_locations/error_location_02.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import 'error_location_02_lib1.dart';
+import 'error_location_02_lib2.dart';
+import 'error_location_02_lib3.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/error_locations/error_location_03.dart.textual_outline.expect b/pkg/front_end/testcases/general/error_locations/error_location_03.dart.textual_outline.expect
new file mode 100644
index 0000000..6ee4f4b
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_locations/error_location_03.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'error_location_03_lib1.dart';
+import 'error_location_03_lib2.dart';
+import 'error_location_03_lib3.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/error_locations/error_location_03.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/error_locations/error_location_03.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6ee4f4b
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_locations/error_location_03.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import 'error_location_03_lib1.dart';
+import 'error_location_03_lib2.dart';
+import 'error_location_03_lib3.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/error_locations/error_location_04.dart.textual_outline.expect b/pkg/front_end/testcases/general/error_locations/error_location_04.dart.textual_outline.expect
new file mode 100644
index 0000000..9dce0c1
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_locations/error_location_04.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'error_location_04_lib1.dart';
+import 'error_location_04_lib2.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/error_locations/error_location_04.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/error_locations/error_location_04.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9dce0c1
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_locations/error_location_04.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'error_location_04_lib1.dart';
+import 'error_location_04_lib2.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/error_locations/error_location_05.dart.textual_outline.expect b/pkg/front_end/testcases/general/error_locations/error_location_05.dart.textual_outline.expect
new file mode 100644
index 0000000..3097149
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_locations/error_location_05.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library error_location_05;
+
+part 'error_location_05_lib1.dart';
diff --git a/pkg/front_end/testcases/general/error_locations/error_location_05.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/error_locations/error_location_05.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3097149
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_locations/error_location_05.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library error_location_05;
+
+part 'error_location_05_lib1.dart';
diff --git a/pkg/front_end/testcases/general/error_locations/error_location_06.dart.textual_outline.expect b/pkg/front_end/testcases/general/error_locations/error_location_06.dart.textual_outline.expect
new file mode 100644
index 0000000..3f290d4
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_locations/error_location_06.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library error_location_06;
+
+part 'error_location_06_lib1.dart';
diff --git a/pkg/front_end/testcases/general/error_locations/error_location_06.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/error_locations/error_location_06.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3f290d4
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_locations/error_location_06.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library error_location_06;
+
+part 'error_location_06_lib1.dart';
diff --git a/pkg/front_end/testcases/general/error_recovery/await_not_in_async.dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/await_not_in_async.dart.textual_outline.expect
new file mode 100644
index 0000000..055b8c6
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/await_not_in_async.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+Future<void> f() => Future.value();
+void g() {}
diff --git a/pkg/front_end/testcases/general/error_recovery/await_not_in_async.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/error_recovery/await_not_in_async.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..055b8c6
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/await_not_in_async.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+Future<void> f() => Future.value();
+void g() {}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart.textual_outline.expect
new file mode 100644
index 0000000..7a39d56
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_general.crash_dart.textual_outline.expect
@@ -0,0 +1,21 @@
+class Foo {
+ foo.x() { }
+ foo.x() : initializer = true { }
+ foo() : initializer = true { }
+ get Foo => 0;
+ get Foo { }
+ get Foo.X ()=> 0;
+ get Foo.X (){ }
+ get Foo (): bla = null => 0;
+ get Foo.X (): bla = null { }
+ set Foo ()=> 0;
+ set Foo (){ }
+ set Foo.X ()=> 0;
+ set Foo.X (){ }
+ set Foo (): bla = null => 0;
+ set Foo.X (): bla = null { }
+ external Foo() : bla = null;
+ external Foo.X() : bla = null { }
+ int Foo;
+ int A, Foo, B;
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart.textual_outline.expect
new file mode 100644
index 0000000..b3cbfd2
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_get.crash_dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class Foo {
+ get foo.x() { }
+ get foo.x() : initializer = true { }
+ get foo() : initializer = true { }
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart.textual_outline.expect
new file mode 100644
index 0000000..d35936c
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_return_type.crash_dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class Foo {
+ void foo.x() { }
+ void foo.x() : initializer = true { }
+ void foo() : initializer = true { }
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart.textual_outline.expect
new file mode 100644
index 0000000..3bf5301
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_bad_name_set.crash_dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class Foo {
+ set foo.x() { }
+ set foo.x() : initializer = true { }
+ set foo() : initializer = true { }
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart.textual_outline.expect
new file mode 100644
index 0000000..3ce8e72
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_get.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class Foo {
+ get Foo() { }
+ get Foo() : initializer = true { }
+ get Foo.x() { }
+ get Foo.x() : initializer = true { }
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_ok.dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_ok.dart.textual_outline.expect
new file mode 100644
index 0000000..2318374
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_ok.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class Foo {
+ Foo() {}
+ Foo() : initializer = true {}
+ Foo.x() {}
+ Foo.x() : initializer = true {}
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_ok.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_ok.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f87cd03
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_ok.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class Foo {
+ Foo() : initializer = true {}
+ Foo() {}
+ Foo.x() : initializer = true {}
+ Foo.x() {}
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart.textual_outline.expect
new file mode 100644
index 0000000..07d90ce
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_operator.crash_dart.textual_outline.expect
@@ -0,0 +1,12 @@
+class Foo {
+ Foo() { }
+ operator/ (): super() { }
+ Foo(){ }
+ .
+ operator/ (): super() { }
+ foo() { }
+ operator/ (): super() { }
+ foo(){ }
+ .
+ operator/ (): super() { }
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart.textual_outline.expect
new file mode 100644
index 0000000..84de529
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_return_type.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class Foo {
+ void Foo() { }
+ void Foo() : initializer = true { }
+ void Foo.x() { }
+ void Foo.x() : initializer = true { }
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart.textual_outline.expect
new file mode 100644
index 0000000..f2dfad0
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/constructor_recovery_set.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class Foo {
+ set Foo() { }
+ set Foo() : initializer = true { }
+ set Foo.x() { }
+ set Foo.x() : initializer = true { }
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.textual_outline.expect
new file mode 100644
index 0000000..386f405
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() async {}
diff --git a/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..386f405
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() async {}
diff --git a/pkg/front_end/testcases/general/error_recovery/empty_for.dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/empty_for.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/empty_for.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/error_recovery/empty_for.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/error_recovery/empty_for.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/empty_for.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39026.crash_dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/issue_39026.crash_dart.textual_outline.expect
new file mode 100644
index 0000000..ef20c09
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39026.crash_dart.textual_outline.expect
@@ -0,0 +1,3 @@
+class A {
+ co operator <() {}
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39026.crash_dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/error_recovery/issue_39026.crash_dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ef20c09
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39026.crash_dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+class A {
+ co operator <() {}
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39026_prime.crash_dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/issue_39026_prime.crash_dart.textual_outline.expect
new file mode 100644
index 0000000..ef20c09
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39026_prime.crash_dart.textual_outline.expect
@@ -0,0 +1,3 @@
+class A {
+ co operator <() {}
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39026_prime.crash_dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/error_recovery/issue_39026_prime.crash_dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ef20c09
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39026_prime.crash_dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+class A {
+ co operator <() {}
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39033.crash_dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/issue_39033.crash_dart.textual_outline.expect
new file mode 100644
index 0000000..2a84e27
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39033.crash_dart.textual_outline.expect
@@ -0,0 +1 @@
+typedef F<Glib>.=;
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39058_prime.crash_dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/issue_39058_prime.crash_dart.textual_outline.expect
new file mode 100644
index 0000000..e042400
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39058_prime.crash_dart.textual_outline.expect
@@ -0,0 +1 @@
+{<[]()>}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39060.dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/issue_39060.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39060.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39060.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/error_recovery/issue_39060.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39060.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart.textual_outline.expect
new file mode 100644
index 0000000..9b170f7
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39202.crash_dart.textual_outline.expect
@@ -0,0 +1,3 @@
+()
+async ()=> a
+b < c $? >;
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39230.crash_dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/issue_39230.crash_dart.textual_outline.expect
new file mode 100644
index 0000000..41e0a64
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39230.crash_dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class C {
+ C() { }
+ operator/ (): super();
+}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39958_01.dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/issue_39958_01.dart.textual_outline.expect
new file mode 100644
index 0000000..5cab0bb
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39958_01.dart.textual_outline.expect
@@ -0,0 +1 @@
+void<int> f() { }
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39958_02.dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/issue_39958_02.dart.textual_outline.expect
new file mode 100644
index 0000000..f03cd81
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39958_02.dart.textual_outline.expect
@@ -0,0 +1 @@
+dynamic<int> f() {}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39958_02.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/error_recovery/issue_39958_02.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f03cd81
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39958_02.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+dynamic<int> f() {}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39958_03.dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/issue_39958_03.dart.textual_outline.expect
new file mode 100644
index 0000000..26e95ee
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39958_03.dart.textual_outline.expect
@@ -0,0 +1 @@
+int<int> f() {}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39958_03.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/error_recovery/issue_39958_03.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..26e95ee
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39958_03.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+int<int> f() {}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39958_04.dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/issue_39958_04.dart.textual_outline.expect
new file mode 100644
index 0000000..78a05ec
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39958_04.dart.textual_outline.expect
@@ -0,0 +1 @@
+Foo<int> f() {}
diff --git a/pkg/front_end/testcases/general/error_recovery/issue_39958_04.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/error_recovery/issue_39958_04.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..78a05ec
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/issue_39958_04.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+Foo<int> f() {}
diff --git a/pkg/front_end/testcases/general/error_recovery/yield_not_in_generator.dart.textual_outline.expect b/pkg/front_end/testcases/general/error_recovery/yield_not_in_generator.dart.textual_outline.expect
new file mode 100644
index 0000000..f9aee8d
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/yield_not_in_generator.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+Future<int> f() => Future.value(7);
+List<int> g() {}
diff --git a/pkg/front_end/testcases/general/error_recovery/yield_not_in_generator.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/error_recovery/yield_not_in_generator.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f9aee8d
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_recovery/yield_not_in_generator.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+Future<int> f() => Future.value(7);
+List<int> g() {}
diff --git a/pkg/front_end/testcases/general/escape.dart.textual_outline.expect b/pkg/front_end/testcases/general/escape.dart.textual_outline.expect
new file mode 100644
index 0000000..55378bb
--- /dev/null
+++ b/pkg/front_end/testcases/general/escape.dart.textual_outline.expect
@@ -0,0 +1,20 @@
+class A {
+ var field;
+}
+
+class B {
+ var field;
+}
+
+class C {
+ operator ==(x) => false;
+}
+
+class X implements A, B {
+ var field;
+}
+
+void useAsA(A object) {}
+void useAsB(B object) {}
+void escape(x) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/escape.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/escape.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d8cd132
--- /dev/null
+++ b/pkg/front_end/testcases/general/escape.dart.textual_outline_modelled.expect
@@ -0,0 +1,20 @@
+class A {
+ var field;
+}
+
+class B {
+ var field;
+}
+
+class C {
+ operator ==(x) => false;
+}
+
+class X implements A, B {
+ var field;
+}
+
+main() {}
+void escape(x) {}
+void useAsA(A object) {}
+void useAsB(B object) {}
diff --git a/pkg/front_end/testcases/general/export_main.dart.textual_outline.expect b/pkg/front_end/testcases/general/export_main.dart.textual_outline.expect
new file mode 100644
index 0000000..8692093
--- /dev/null
+++ b/pkg/front_end/testcases/general/export_main.dart.textual_outline.expect
@@ -0,0 +1 @@
+export 'hello.dart' show main;
diff --git a/pkg/front_end/testcases/general/export_main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/export_main.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8692093
--- /dev/null
+++ b/pkg/front_end/testcases/general/export_main.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+export 'hello.dart' show main;
diff --git a/pkg/front_end/testcases/general/export_test.dart.textual_outline.expect b/pkg/front_end/testcases/general/export_test.dart.textual_outline.expect
new file mode 100644
index 0000000..069d6b3
--- /dev/null
+++ b/pkg/front_end/testcases/general/export_test.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'dart:developer' show UserTag;
+export 'dart:core' show print;
+
+main() {}
diff --git a/pkg/front_end/testcases/general/export_test.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/export_test.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..069d6b3
--- /dev/null
+++ b/pkg/front_end/testcases/general/export_test.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'dart:developer' show UserTag;
+export 'dart:core' show print;
+
+main() {}
diff --git a/pkg/front_end/testcases/general/expressions.dart.textual_outline.expect b/pkg/front_end/testcases/general/expressions.dart.textual_outline.expect
new file mode 100644
index 0000000..bfda72e
--- /dev/null
+++ b/pkg/front_end/testcases/general/expressions.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+foo({fisk}) {}
+caller(f) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/expressions.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/expressions.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a1c989b
--- /dev/null
+++ b/pkg/front_end/testcases/general/expressions.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+caller(f) {}
+foo({fisk}) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/extend_with_type_variable.dart.textual_outline.expect b/pkg/front_end/testcases/general/extend_with_type_variable.dart.textual_outline.expect
new file mode 100644
index 0000000..0ff9f7d
--- /dev/null
+++ b/pkg/front_end/testcases/general/extend_with_type_variable.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class SuperClass {}
+
+mixin Mixin<T> {}
+
+class Class1<T, S extends SuperClass> extends S with Mixin<T> {}
+
+class Class2<T, M extends Mixin<T>> extends SuperClass with M {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/extend_with_type_variable.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/extend_with_type_variable.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..975364e
--- /dev/null
+++ b/pkg/front_end/testcases/general/extend_with_type_variable.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+class Class1<T, S extends SuperClass> extends S with Mixin<T> {}
+
+class Class2<T, M extends Mixin<T>> extends SuperClass with M {}
+
+class SuperClass {}
+
+main() {}
+mixin Mixin<T> {}
diff --git a/pkg/front_end/testcases/general/external.dart.textual_outline.expect b/pkg/front_end/testcases/general/external.dart.textual_outline.expect
new file mode 100644
index 0000000..fbcbaee
--- /dev/null
+++ b/pkg/front_end/testcases/general/external.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'dart:isolate';
+
+var subscription;
+void onData(x) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/external.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/external.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1db5cd5
--- /dev/null
+++ b/pkg/front_end/testcases/general/external.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import 'dart:isolate';
+
+main() {}
+var subscription;
+void onData(x) {}
diff --git a/pkg/front_end/testcases/general/external_import.dart.textual_outline.expect b/pkg/front_end/testcases/general/external_import.dart.textual_outline.expect
new file mode 100644
index 0000000..e1f051e
--- /dev/null
+++ b/pkg/front_end/testcases/general/external_import.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'dart-ext:here';
+import 'dart-ext:foo/../there';
+import 'dart-ext:/usr/local/somewhere';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/external_import.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/external_import.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e1f051e
--- /dev/null
+++ b/pkg/front_end/testcases/general/external_import.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import 'dart-ext:here';
+import 'dart-ext:foo/../there';
+import 'dart-ext:/usr/local/somewhere';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/fallthrough.dart.textual_outline.expect b/pkg/front_end/testcases/general/fallthrough.dart.textual_outline.expect
new file mode 100644
index 0000000..64fdb31
--- /dev/null
+++ b/pkg/front_end/testcases/general/fallthrough.dart.textual_outline.expect
@@ -0,0 +1 @@
+void main(List<String> args) {}
diff --git a/pkg/front_end/testcases/general/fallthrough.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/fallthrough.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..64fdb31
--- /dev/null
+++ b/pkg/front_end/testcases/general/fallthrough.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+void main(List<String> args) {}
diff --git a/pkg/front_end/testcases/general/ffi_sample.dart.textual_outline.expect b/pkg/front_end/testcases/general/ffi_sample.dart.textual_outline.expect
new file mode 100644
index 0000000..eb10d58
--- /dev/null
+++ b/pkg/front_end/testcases/general/ffi_sample.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+import 'dart:ffi';
+import "package:ffi/ffi.dart";
+
+class Coordinate extends Struct {
+ @Double()
+ double x;
+ @Double()
+ double y;
+ Pointer<Coordinate> next;
+ factory Coordinate.allocate(double x, double y, Pointer<Coordinate> next) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/ffi_sample.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/ffi_sample.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..eb10d58
--- /dev/null
+++ b/pkg/front_end/testcases/general/ffi_sample.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+import 'dart:ffi';
+import "package:ffi/ffi.dart";
+
+class Coordinate extends Struct {
+ @Double()
+ double x;
+ @Double()
+ double y;
+ Pointer<Coordinate> next;
+ factory Coordinate.allocate(double x, double y, Pointer<Coordinate> next) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/fibonacci.dart.textual_outline.expect b/pkg/front_end/testcases/general/fibonacci.dart.textual_outline.expect
new file mode 100644
index 0000000..178655b
--- /dev/null
+++ b/pkg/front_end/testcases/general/fibonacci.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+int fibonacci(int n) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/fibonacci.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/fibonacci.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..178655b
--- /dev/null
+++ b/pkg/front_end/testcases/general/fibonacci.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+int fibonacci(int n) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/for_in_scope.dart.textual_outline.expect b/pkg/front_end/testcases/general/for_in_scope.dart.textual_outline.expect
new file mode 100644
index 0000000..24765f4
--- /dev/null
+++ b/pkg/front_end/testcases/general/for_in_scope.dart.textual_outline.expect
@@ -0,0 +1 @@
+main(List<String> arguments) {}
diff --git a/pkg/front_end/testcases/general/for_in_scope.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/for_in_scope.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..24765f4
--- /dev/null
+++ b/pkg/front_end/testcases/general/for_in_scope.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main(List<String> arguments) {}
diff --git a/pkg/front_end/testcases/general/for_in_without_declaration.dart.textual_outline.expect b/pkg/front_end/testcases/general/for_in_without_declaration.dart.textual_outline.expect
new file mode 100644
index 0000000..1b8a2ec
--- /dev/null
+++ b/pkg/front_end/testcases/general/for_in_without_declaration.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+bool topLevelField;
+var untypedTopLevelField;
+
+class Super {
+ int superInstanceField;
+ var untypedSuperInstanceField;
+}
+
+class C extends Super {
+ int instanceField;
+ var untypedInstanceField;
+ static double staticField;
+ static var untypedStaticField;
+ m() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/for_in_without_declaration.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/for_in_without_declaration.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..82cde47
--- /dev/null
+++ b/pkg/front_end/testcases/general/for_in_without_declaration.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+bool topLevelField;
+
+class C extends Super {
+ int instanceField;
+ m() {}
+ static double staticField;
+ static var untypedStaticField;
+ var untypedInstanceField;
+}
+
+class Super {
+ int superInstanceField;
+ var untypedSuperInstanceField;
+}
+
+main() {}
+var untypedTopLevelField;
diff --git a/pkg/front_end/testcases/general/forwarding_stub_for_operator.dart.textual_outline.expect b/pkg/front_end/testcases/general/forwarding_stub_for_operator.dart.textual_outline.expect
new file mode 100644
index 0000000..c81b41e
--- /dev/null
+++ b/pkg/front_end/testcases/general/forwarding_stub_for_operator.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+class A {
+ dynamic operator +(covariant int a) => null;
+}
+
+class B {
+ dynamic operator +(dynamic b) => null;
+}
+
+abstract class C implements A, B {}
+
+class D {
+ dynamic operator +(dynamic d) => null;
+}
+
+class E extends D {
+ dynamic operator +(covariant int e);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/forwarding_stub_for_operator.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/forwarding_stub_for_operator.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e1eb7ad
--- /dev/null
+++ b/pkg/front_end/testcases/general/forwarding_stub_for_operator.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+abstract class C implements A, B {}
+
+class A {
+ dynamic operator +(covariant int a) => null;
+}
+
+class B {
+ dynamic operator +(dynamic b) => null;
+}
+
+class D {
+ dynamic operator +(dynamic d) => null;
+}
+
+class E extends D {
+ dynamic operator +(covariant int e);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/function_in_field.dart.textual_outline.expect b/pkg/front_end/testcases/general/function_in_field.dart.textual_outline.expect
new file mode 100644
index 0000000..48b83ef
--- /dev/null
+++ b/pkg/front_end/testcases/general/function_in_field.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+var x = () {
+ var y = 42;
+ return y;
+};
+main() {}
diff --git a/pkg/front_end/testcases/general/function_in_field.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/function_in_field.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..dde78ba
--- /dev/null
+++ b/pkg/front_end/testcases/general/function_in_field.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+main() {}
+var x = () {
+ var y = 42;
+ return y;
+};
diff --git a/pkg/front_end/testcases/general/function_type_assignments.dart.textual_outline.expect b/pkg/front_end/testcases/general/function_type_assignments.dart.textual_outline.expect
new file mode 100644
index 0000000..4e7d345
--- /dev/null
+++ b/pkg/front_end/testcases/general/function_type_assignments.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+T identity<T>(T t) => t;
+T identityObject<T extends Object>(T t) => t;
+T identityList<T extends List<T>>(T t) => t;
+String x = identity;
+String y = identityObject;
+String z = identityList;
+main() {}
diff --git a/pkg/front_end/testcases/general/function_type_assignments.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/function_type_assignments.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..260816e
--- /dev/null
+++ b/pkg/front_end/testcases/general/function_type_assignments.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+String x = identity;
+String y = identityObject;
+String z = identityList;
+T identity<T>(T t) => t;
+T identityList<T extends List<T>>(T t) => t;
+T identityObject<T extends Object>(T t) => t;
+main() {}
diff --git a/pkg/front_end/testcases/general/function_type_default_value.dart.textual_outline.expect b/pkg/front_end/testcases/general/function_type_default_value.dart.textual_outline.expect
new file mode 100644
index 0000000..5b2ed24
--- /dev/null
+++ b/pkg/front_end/testcases/general/function_type_default_value.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+void Function({obj: Object}) x;
+main() { }
diff --git a/pkg/front_end/testcases/general/function_type_is_check.dart.textual_outline.expect b/pkg/front_end/testcases/general/function_type_is_check.dart.textual_outline.expect
new file mode 100644
index 0000000..0f294ea
--- /dev/null
+++ b/pkg/front_end/testcases/general/function_type_is_check.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import "package:expect/expect.dart" show Expect;
+
+test(f) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/function_type_is_check.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/function_type_is_check.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..22e03b0
--- /dev/null
+++ b/pkg/front_end/testcases/general/function_type_is_check.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import "package:expect/expect.dart" show Expect;
+
+main() {}
+test(f) {}
diff --git a/pkg/front_end/testcases/general/function_type_recovery.dart.textual_outline.expect b/pkg/front_end/testcases/general/function_type_recovery.dart.textual_outline.expect
new file mode 100644
index 0000000..2efaae2
--- /dev/null
+++ b/pkg/front_end/testcases/general/function_type_recovery.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+typedef F = int Function(int f(String x));
+main() {}
diff --git a/pkg/front_end/testcases/general/function_type_recovery.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/function_type_recovery.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a2bb0c0
--- /dev/null
+++ b/pkg/front_end/testcases/general/function_type_recovery.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+main() {}
+typedef F = int Function(int f(String x));
diff --git a/pkg/front_end/testcases/general/functions.dart.textual_outline.expect b/pkg/front_end/testcases/general/functions.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/functions.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/functions.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/functions.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/functions.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/future_or_test.dart.textual_outline.expect b/pkg/front_end/testcases/general/future_or_test.dart.textual_outline.expect
new file mode 100644
index 0000000..e798df9
--- /dev/null
+++ b/pkg/front_end/testcases/general/future_or_test.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+import 'dart:async';
+
+class A {
+ dynamic foo() => null;
+}
+
+class B {
+ A a;
+ Future<dynamic> bar() async => a.foo();
+}
+
+class C {
+ B b = B();
+ Future<int> baz() async => b.bar();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/future_or_test.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/future_or_test.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e798df9
--- /dev/null
+++ b/pkg/front_end/testcases/general/future_or_test.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+import 'dart:async';
+
+class A {
+ dynamic foo() => null;
+}
+
+class B {
+ A a;
+ Future<dynamic> bar() async => a.foo();
+}
+
+class C {
+ B b = B();
+ Future<int> baz() async => b.bar();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/generic_function_type_in_message.dart.textual_outline.expect b/pkg/front_end/testcases/general/generic_function_type_in_message.dart.textual_outline.expect
new file mode 100644
index 0000000..8711ddc
--- /dev/null
+++ b/pkg/front_end/testcases/general/generic_function_type_in_message.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+num add<A extends num, B extends num>(A a, B b) => a + b;
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/generic_function_type_in_message.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/generic_function_type_in_message.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3eb959f
--- /dev/null
+++ b/pkg/front_end/testcases/general/generic_function_type_in_message.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+main() {}
+num add<A extends num, B extends num>(A a, B b) => a + b;
+test() {}
diff --git a/pkg/front_end/testcases/general/getter_call.dart.textual_outline.expect b/pkg/front_end/testcases/general/getter_call.dart.textual_outline.expect
new file mode 100644
index 0000000..d9d43c9
--- /dev/null
+++ b/pkg/front_end/testcases/general/getter_call.dart.textual_outline.expect
@@ -0,0 +1,52 @@
+bool enableRead = true;
+int read(int value) => enableRead ? value : -1;
+int method1() => 0;
+int method2(int a) => -a;
+int method3(int a, int b) => a - b;
+int method4(int a, [int b = 0]) => a - b;
+int method5([int a = 0, int b = 0]) => a - b;
+int method6(int a, {int b = 0}) => a - b;
+int method7({int a = 0, int b = 0}) => a - b;
+
+class Class {
+ Function field1a = method1;
+ int Function() field1b = method1;
+ int Function(int a) field2 = method2;
+ int Function(int a, int b) field3 = method3;
+ int Function(int a, [int b]) field4 = method4;
+ int Function([int a, int b]) field5 = method5;
+ int Function(int a, {int b}) field6 = method6;
+ int Function({int a, int b}) field7 = method7;
+ Function get getter1a => method1;
+ int Function() get getter1b => method1;
+ int Function(int a) get getter2 => method2;
+ int Function(int a, int b) get getter3 => method3;
+ int Function(int a, [int b]) get getter4 => method4;
+ int Function([int a, int b]) get getter5 => method5;
+ int Function(int a, {int b}) get getter6 => method6;
+ int Function({int a, int b}) get getter7 => method7;
+}
+
+class Subclass extends Class {
+ Function get field1a {}
+ int Function() get field1b {}
+ int Function(int a) get field2 {}
+ int Function(int a, int b) get field3 {}
+ int Function(int a, [int b]) get field4 {}
+ int Function([int a, int b]) get field5 {}
+ int Function(int a, {int b}) get field6 {}
+ int Function({int a, int b}) get field7 {}
+ Function get getter1a {}
+ int Function() get getter1b {}
+ int Function(int a) get getter2 {}
+ int Function(int a, int b) get getter3 {}
+ int Function(int a, [int b]) get getter4 {}
+ int Function([int a, int b]) get getter5 {}
+ int Function(int a, {int b}) get getter6 {}
+ int Function({int a, int b}) get getter7 {}
+}
+
+main() {}
+callField(Class c) {}
+callGetter(Class c) {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/general/getter_call.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/getter_call.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fafec6e
--- /dev/null
+++ b/pkg/front_end/testcases/general/getter_call.dart.textual_outline_modelled.expect
@@ -0,0 +1,52 @@
+bool enableRead = true;
+callField(Class c) {}
+callGetter(Class c) {}
+
+class Class {
+ Function field1a = method1;
+ Function get getter1a => method1;
+ int Function() field1b = method1;
+ int Function() get getter1b => method1;
+ int Function([int a, int b]) field5 = method5;
+ int Function([int a, int b]) get getter5 => method5;
+ int Function(int a) field2 = method2;
+ int Function(int a) get getter2 => method2;
+ int Function(int a, [int b]) field4 = method4;
+ int Function(int a, [int b]) get getter4 => method4;
+ int Function(int a, int b) field3 = method3;
+ int Function(int a, int b) get getter3 => method3;
+ int Function(int a, {int b}) field6 = method6;
+ int Function(int a, {int b}) get getter6 => method6;
+ int Function({int a, int b}) field7 = method7;
+ int Function({int a, int b}) get getter7 => method7;
+}
+
+class Subclass extends Class {
+ Function get field1a {}
+ Function get getter1a {}
+ int Function() get field1b {}
+ int Function() get getter1b {}
+ int Function([int a, int b]) get field5 {}
+ int Function([int a, int b]) get getter5 {}
+ int Function(int a) get field2 {}
+ int Function(int a) get getter2 {}
+ int Function(int a, [int b]) get field4 {}
+ int Function(int a, [int b]) get getter4 {}
+ int Function(int a, int b) get field3 {}
+ int Function(int a, int b) get getter3 {}
+ int Function(int a, {int b}) get field6 {}
+ int Function(int a, {int b}) get getter6 {}
+ int Function({int a, int b}) get field7 {}
+ int Function({int a, int b}) get getter7 {}
+}
+
+expect(expected, actual) {}
+int method1() => 0;
+int method2(int a) => -a;
+int method3(int a, int b) => a - b;
+int method4(int a, [int b = 0]) => a - b;
+int method5([int a = 0, int b = 0]) => a - b;
+int method6(int a, {int b = 0}) => a - b;
+int method7({int a = 0, int b = 0}) => a - b;
+int read(int value) => enableRead ? value : -1;
+main() {}
diff --git a/pkg/front_end/testcases/general/having_part_with_part_and_annotation.dart.textual_outline.expect b/pkg/front_end/testcases/general/having_part_with_part_and_annotation.dart.textual_outline.expect
new file mode 100644
index 0000000..b2d893c
--- /dev/null
+++ b/pkg/front_end/testcases/general/having_part_with_part_and_annotation.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+@Foo
+part 'having_part_with_part_and_annotation_lib1.dart';
+
+const int Foo = 42;
+void fromMain() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/having_part_with_part_and_annotation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/having_part_with_part_and_annotation.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4ce86ce
--- /dev/null
+++ b/pkg/front_end/testcases/general/having_part_with_part_and_annotation.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+@Foo
+part 'having_part_with_part_and_annotation_lib1.dart';
+
+const int Foo = 42;
+main() {}
+void fromMain() {}
diff --git a/pkg/front_end/testcases/general/having_part_with_parts_and_annotation.dart.textual_outline.expect b/pkg/front_end/testcases/general/having_part_with_parts_and_annotation.dart.textual_outline.expect
new file mode 100644
index 0000000..24ca63b
--- /dev/null
+++ b/pkg/front_end/testcases/general/having_part_with_parts_and_annotation.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+@Foo
+part 'having_part_with_parts_and_annotation_lib1.dart';
+
+const int Foo = 42;
+void fromMain() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/having_part_with_parts_and_annotation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/having_part_with_parts_and_annotation.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..754ba3f
--- /dev/null
+++ b/pkg/front_end/testcases/general/having_part_with_parts_and_annotation.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+@Foo
+part 'having_part_with_parts_and_annotation_lib1.dart';
+
+const int Foo = 42;
+main() {}
+void fromMain() {}
diff --git a/pkg/front_end/testcases/general/hello.dart.textual_outline.expect b/pkg/front_end/testcases/general/hello.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/hello.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/hello.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/hello.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/hello.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/if_null_in_cascade.dart.textual_outline.expect b/pkg/front_end/testcases/general/if_null_in_cascade.dart.textual_outline.expect
new file mode 100644
index 0000000..c83fa07
--- /dev/null
+++ b/pkg/front_end/testcases/general/if_null_in_cascade.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class Class {
+ method() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/if_null_in_cascade.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/if_null_in_cascade.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c83fa07
--- /dev/null
+++ b/pkg/front_end/testcases/general/if_null_in_cascade.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+class Class {
+ method() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/if_null_in_list_literal.dart.textual_outline.expect b/pkg/front_end/testcases/general/if_null_in_list_literal.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/if_null_in_list_literal.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/if_null_in_list_literal.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/if_null_in_list_literal.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/if_null_in_list_literal.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/if_null_in_set_literal.dart.textual_outline.expect b/pkg/front_end/testcases/general/if_null_in_set_literal.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/if_null_in_set_literal.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/if_null_in_set_literal.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/if_null_in_set_literal.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/if_null_in_set_literal.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/ignore_function.dart.textual_outline.expect b/pkg/front_end/testcases/general/ignore_function.dart.textual_outline.expect
new file mode 100644
index 0000000..81dde83
--- /dev/null
+++ b/pkg/front_end/testcases/general/ignore_function.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+import "dart:core" as core;
+
+class A implements core.Function {
+ operator ==(other) => false;
+}
+
+class B implements Function {
+ operator ==(other) => false;
+}
+
+class Function {
+ core.bool operator ==(core.Object other) => false;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/ignore_function.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/ignore_function.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..81dde83
--- /dev/null
+++ b/pkg/front_end/testcases/general/ignore_function.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+import "dart:core" as core;
+
+class A implements core.Function {
+ operator ==(other) => false;
+}
+
+class B implements Function {
+ operator ==(other) => false;
+}
+
+class Function {
+ core.bool operator ==(core.Object other) => false;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/illegal_named_function_expression.dart.textual_outline.expect b/pkg/front_end/testcases/general/illegal_named_function_expression.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/illegal_named_function_expression.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/illegal_named_function_expression.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/illegal_named_function_expression.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/illegal_named_function_expression.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/illegal_named_function_expression_scope.dart.textual_outline.expect b/pkg/front_end/testcases/general/illegal_named_function_expression_scope.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/illegal_named_function_expression_scope.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/illegal_named_function_expression_scope.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/illegal_named_function_expression_scope.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/illegal_named_function_expression_scope.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/implicit_const_with_static_fields.dart.textual_outline.expect b/pkg/front_end/testcases/general/implicit_const_with_static_fields.dart.textual_outline.expect
new file mode 100644
index 0000000..31deaf6
--- /dev/null
+++ b/pkg/front_end/testcases/general/implicit_const_with_static_fields.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+const constTopLevelField = 42;
+
+class C {
+ const C(x);
+ static const constField = 87;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/implicit_const_with_static_fields.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/implicit_const_with_static_fields.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7a87544
--- /dev/null
+++ b/pkg/front_end/testcases/general/implicit_const_with_static_fields.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class C {
+ const C(x);
+ static const constField = 87;
+}
+
+const constTopLevelField = 42;
+main() {}
diff --git a/pkg/front_end/testcases/general/implicit_new.dart.textual_outline.expect b/pkg/front_end/testcases/general/implicit_new.dart.textual_outline.expect
new file mode 100644
index 0000000..c3f5004
--- /dev/null
+++ b/pkg/front_end/testcases/general/implicit_new.dart.textual_outline.expect
@@ -0,0 +1,20 @@
+import "implicit_new.dart" as prefix;
+
+class Foo {
+ operator +(other) => null;
+}
+
+class Bar {
+ Bar.named();
+ operator +(other) => null;
+}
+
+testNSM() {}
+f(x) => x;
+
+class IndexTester {
+ operator [](_) => null;
+ void operator []=(_a, _b) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/implicit_new.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/implicit_new.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..72ae030
--- /dev/null
+++ b/pkg/front_end/testcases/general/implicit_new.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+import "implicit_new.dart" as prefix;
+
+class Bar {
+ Bar.named();
+ operator +(other) => null;
+}
+
+class Foo {
+ operator +(other) => null;
+}
+
+class IndexTester {
+ operator [](_) => null;
+ void operator []=(_a, _b) {}
+}
+
+f(x) => x;
+main() {}
+testNSM() {}
diff --git a/pkg/front_end/testcases/general/implicit_scope_test.dart.textual_outline.expect b/pkg/front_end/testcases/general/implicit_scope_test.dart.textual_outline.expect
new file mode 100644
index 0000000..ea2f363
--- /dev/null
+++ b/pkg/front_end/testcases/general/implicit_scope_test.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+import "package:expect/expect.dart";
+
+class ImplicitScopeTest {
+ static bool alwaysTrue() {}
+ static testMain() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/implicit_scope_test.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/implicit_scope_test.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ea2f363
--- /dev/null
+++ b/pkg/front_end/testcases/general/implicit_scope_test.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+import "package:expect/expect.dart";
+
+class ImplicitScopeTest {
+ static bool alwaysTrue() {}
+ static testMain() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/implicit_this.dart.textual_outline.expect b/pkg/front_end/testcases/general/implicit_this.dart.textual_outline.expect
new file mode 100644
index 0000000..663566a
--- /dev/null
+++ b/pkg/front_end/testcases/general/implicit_this.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class C {
+ m() {}
+ testC() {}
+}
+
+class D extends C {
+ testD() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/implicit_this.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/implicit_this.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..663566a
--- /dev/null
+++ b/pkg/front_end/testcases/general/implicit_this.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+class C {
+ m() {}
+ testC() {}
+}
+
+class D extends C {
+ testD() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/import_conflicting_getters.dart.textual_outline.expect b/pkg/front_end/testcases/general/import_conflicting_getters.dart.textual_outline.expect
new file mode 100644
index 0000000..4e8aa56
--- /dev/null
+++ b/pkg/front_end/testcases/general/import_conflicting_getters.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'import_conflicting_getters_lib1.dart';
+import 'import_conflicting_getters_lib2.dart';
+
+main() {}
+errors() {}
diff --git a/pkg/front_end/testcases/general/import_conflicting_getters.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/import_conflicting_getters.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2c010bc
--- /dev/null
+++ b/pkg/front_end/testcases/general/import_conflicting_getters.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import 'import_conflicting_getters_lib1.dart';
+import 'import_conflicting_getters_lib2.dart';
+
+errors() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/import_conflicting_setters.dart.textual_outline.expect b/pkg/front_end/testcases/general/import_conflicting_setters.dart.textual_outline.expect
new file mode 100644
index 0000000..9f1f251
--- /dev/null
+++ b/pkg/front_end/testcases/general/import_conflicting_setters.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'import_conflicting_setters_lib1.dart';
+import 'import_conflicting_setters_lib2.dart';
+
+main() {}
+errors() {}
diff --git a/pkg/front_end/testcases/general/import_conflicting_setters.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/import_conflicting_setters.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4bc9bf2
--- /dev/null
+++ b/pkg/front_end/testcases/general/import_conflicting_setters.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import 'import_conflicting_setters_lib1.dart';
+import 'import_conflicting_setters_lib2.dart';
+
+errors() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/import_conflicting_type_member.dart.textual_outline.expect b/pkg/front_end/testcases/general/import_conflicting_type_member.dart.textual_outline.expect
new file mode 100644
index 0000000..5f91bbc
--- /dev/null
+++ b/pkg/front_end/testcases/general/import_conflicting_type_member.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'import_conflicting_type_member_lib1.dart';
+import 'import_conflicting_type_member_lib2.dart';
+
+main() {}
+errors() {}
diff --git a/pkg/front_end/testcases/general/import_conflicting_type_member.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/import_conflicting_type_member.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4574f84
--- /dev/null
+++ b/pkg/front_end/testcases/general/import_conflicting_type_member.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import 'import_conflicting_type_member_lib1.dart';
+import 'import_conflicting_type_member_lib2.dart';
+
+errors() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/import_conflicting_types.dart.textual_outline.expect b/pkg/front_end/testcases/general/import_conflicting_types.dart.textual_outline.expect
new file mode 100644
index 0000000..1d6b54a
--- /dev/null
+++ b/pkg/front_end/testcases/general/import_conflicting_types.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'import_conflicting_types_lib1.dart';
+import 'import_conflicting_types_lib2.dart';
+
+main() {}
+errors() {}
diff --git a/pkg/front_end/testcases/general/import_conflicting_types.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/import_conflicting_types.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8b0c6e4
--- /dev/null
+++ b/pkg/front_end/testcases/general/import_conflicting_types.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import 'import_conflicting_types_lib1.dart';
+import 'import_conflicting_types_lib2.dart';
+
+errors() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/incomplete_field_formal_parameter.dart.textual_outline.expect b/pkg/front_end/testcases/general/incomplete_field_formal_parameter.dart.textual_outline.expect
new file mode 100644
index 0000000..5811235
--- /dev/null
+++ b/pkg/front_end/testcases/general/incomplete_field_formal_parameter.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class C {
+ C.a(this.);
+ C.b(this.);
+ C.c(this., p);
+ C.d(this., p);
+}
diff --git a/pkg/front_end/testcases/general/infer_field_from_multiple.dart.textual_outline.expect b/pkg/front_end/testcases/general/infer_field_from_multiple.dart.textual_outline.expect
new file mode 100644
index 0000000..9131faf
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_field_from_multiple.dart.textual_outline.expect
@@ -0,0 +1,121 @@
+class A<T> {
+ var field1 = 0;
+ var field2 = 0;
+ var field3 = 0;
+ var field4 = 0;
+ int field5;
+ int field6;
+ int field7;
+ int field8;
+ var field9;
+ T field10;
+ T field11;
+ T field12;
+ T field13;
+ T field14;
+ var field15 = 0;
+ int field16;
+ var field17 = 0;
+ int field18;
+}
+
+class B<T, S> {
+ var field1 = 1;
+ var field2 = '';
+ var field3 = 1;
+ var field4 = '';
+ int field5;
+ String field6;
+ int field7;
+ String field8;
+ var field9;
+ T field10;
+ S field11;
+ T field12;
+ T field13;
+ S field14;
+ int field15;
+ var field16 = 0;
+ String field17;
+ var field18 = '';
+}
+
+class C implements A<int>, B<int, String> {
+ var field1;
+ var field2;
+ var field3 = 0;
+ var field4 = 0;
+ var field5;
+ var field6;
+ var field7 = 0;
+ var field8 = 0;
+ var field9;
+ var field10;
+ var field11;
+ int field12;
+ var field13 = 0;
+ int field14;
+ var field15;
+ var field16;
+ var field17;
+ var field18;
+ C(
+ this.field1,
+ this.field2,
+ this.field3,
+ this.field4,
+ this.field5,
+ this.field6,
+ this.field7,
+ this.field8,
+ this.field9,
+ this.field10,
+ this.field11,
+ this.field12,
+ this.field13,
+ this.field14,
+ this.field15,
+ this.field16,
+ this.field17,
+ this.field18);
+}
+
+class D<T> implements A<T>, B<T, T> {
+ var field1;
+ var field2;
+ var field3 = 0;
+ var field4 = 0;
+ var field5;
+ var field6;
+ var field7 = 0;
+ var field8 = 0;
+ var field9;
+ var field10;
+ var field11;
+ T field12;
+ var field13 = null;
+ T field14;
+ var field15;
+ var field16;
+ var field17;
+ var field18;
+ D(
+ this.field1,
+ this.field2,
+ this.field3,
+ this.field4,
+ this.field5,
+ this.field6,
+ this.field7,
+ this.field8,
+ this.field9,
+ this.field10,
+ this.field11,
+ this.field12,
+ this.field13,
+ this.field14,
+ this.field15,
+ this.field16,
+ this.field17,
+ this.field18);
+}
diff --git a/pkg/front_end/testcases/general/infer_field_from_multiple.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/infer_field_from_multiple.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b2f2254
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_field_from_multiple.dart.textual_outline_modelled.expect
@@ -0,0 +1,121 @@
+class A<T> {
+ T field10;
+ T field11;
+ T field12;
+ T field13;
+ T field14;
+ int field16;
+ int field18;
+ int field5;
+ int field6;
+ int field7;
+ int field8;
+ var field1 = 0;
+ var field15 = 0;
+ var field17 = 0;
+ var field2 = 0;
+ var field3 = 0;
+ var field4 = 0;
+ var field9;
+}
+
+class B<T, S> {
+ S field11;
+ S field14;
+ String field17;
+ String field6;
+ String field8;
+ T field10;
+ T field12;
+ T field13;
+ int field15;
+ int field5;
+ int field7;
+ var field1 = 1;
+ var field16 = 0;
+ var field18 = '';
+ var field2 = '';
+ var field3 = 1;
+ var field4 = '';
+ var field9;
+}
+
+class C implements A<int>, B<int, String> {
+ C(
+ this.field1,
+ this.field2,
+ this.field3,
+ this.field4,
+ this.field5,
+ this.field6,
+ this.field7,
+ this.field8,
+ this.field9,
+ this.field10,
+ this.field11,
+ this.field12,
+ this.field13,
+ this.field14,
+ this.field15,
+ this.field16,
+ this.field17,
+ this.field18);
+ int field12;
+ int field14;
+ var field10;
+ var field11;
+ var field13 = 0;
+ var field15;
+ var field16;
+ var field17;
+ var field18;
+ var field1;
+ var field2;
+ var field3 = 0;
+ var field4 = 0;
+ var field5;
+ var field6;
+ var field7 = 0;
+ var field8 = 0;
+ var field9;
+}
+
+class D<T> implements A<T>, B<T, T> {
+ D(
+ this.field1,
+ this.field2,
+ this.field3,
+ this.field4,
+ this.field5,
+ this.field6,
+ this.field7,
+ this.field8,
+ this.field9,
+ this.field10,
+ this.field11,
+ this.field12,
+ this.field13,
+ this.field14,
+ this.field15,
+ this.field16,
+ this.field17,
+ this.field18);
+ T field12;
+ T field14;
+ var field10;
+ var field11;
+ var field13 = null;
+ var field15;
+ var field16;
+ var field17;
+ var field18;
+ var field1;
+ var field2;
+ var field3 = 0;
+ var field4 = 0;
+ var field5;
+ var field6;
+ var field7 = 0;
+ var field8 = 0;
+ var field9;
+}
diff --git a/pkg/front_end/testcases/general/infer_field_type.dart.textual_outline.expect b/pkg/front_end/testcases/general/infer_field_type.dart.textual_outline.expect
new file mode 100644
index 0000000..42aad86
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_field_type.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+class C extends B {
+ var field;
+}
+
+class B extends A {
+ get field => null;
+ set field(value) {}
+}
+
+class A {
+ var field = 0;
+}
+
+var topLevelFieldFromA = new A().field;
+var topLevelFieldFromB = new B().field;
+var topLevelFieldFromC = new C().field;
+main() {}
diff --git a/pkg/front_end/testcases/general/infer_field_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/infer_field_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..69cf59c
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_field_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+class A {
+ var field = 0;
+}
+
+class B extends A {
+ get field => null;
+ set field(value) {}
+}
+
+class C extends B {
+ var field;
+}
+
+main() {}
+var topLevelFieldFromA = new A().field;
+var topLevelFieldFromB = new B().field;
+var topLevelFieldFromC = new C().field;
diff --git a/pkg/front_end/testcases/general/infer_fixed_generic_return_type.dart.textual_outline.expect b/pkg/front_end/testcases/general/infer_fixed_generic_return_type.dart.textual_outline.expect
new file mode 100644
index 0000000..b5af5e7
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_fixed_generic_return_type.dart.textual_outline.expect
@@ -0,0 +1,27 @@
+abstract class Base {}
+
+abstract class MixinA<T> {
+ T method(Object t);
+}
+
+abstract class Class extends Base with MixinA {
+ method(t) {}
+}
+
+abstract class YamlNode {}
+
+abstract class Map<K, V> {
+ V operator [](Object key);
+}
+
+abstract class MapMixin<K, V> implements Map<K, V> {
+ V operator [](Object key);
+}
+
+abstract class UnmodifiableMapMixin<K, V> implements Map<K, V> {}
+
+class YamlMap extends YamlNode with MapMixin, UnmodifiableMapMixin {
+ operator [](key) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/infer_fixed_generic_return_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/infer_fixed_generic_return_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e13a164
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_fixed_generic_return_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,27 @@
+abstract class Base {}
+
+abstract class Class extends Base with MixinA {
+ method(t) {}
+}
+
+abstract class Map<K, V> {
+ V operator [](Object key);
+}
+
+abstract class MapMixin<K, V> implements Map<K, V> {
+ V operator [](Object key);
+}
+
+abstract class MixinA<T> {
+ T method(Object t);
+}
+
+abstract class UnmodifiableMapMixin<K, V> implements Map<K, V> {}
+
+abstract class YamlNode {}
+
+class YamlMap extends YamlNode with MapMixin, UnmodifiableMapMixin {
+ operator [](key) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/infer_map_literal_with_closure.dart.textual_outline.expect b/pkg/front_end/testcases/general/infer_map_literal_with_closure.dart.textual_outline.expect
new file mode 100644
index 0000000..e1d5d9a
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_map_literal_with_closure.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class Class {
+ var map = {
+ 'foo': (String a) {
+ int c = a.length;
+ }
+ };
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/infer_map_literal_with_closure.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/infer_map_literal_with_closure.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e1d5d9a
--- /dev/null
+++ b/pkg/front_end/testcases/general/infer_map_literal_with_closure.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class Class {
+ var map = {
+ 'foo': (String a) {
+ int c = a.length;
+ }
+ };
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/inherit_function.dart.textual_outline.expect b/pkg/front_end/testcases/general/inherit_function.dart.textual_outline.expect
new file mode 100644
index 0000000..a94f799
--- /dev/null
+++ b/pkg/front_end/testcases/general/inherit_function.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+class A implements Function {}
+
+class B extends Function {}
+
+class C extends Object with Function {}
+
+class D = Object with Function;
+main() {}
diff --git a/pkg/front_end/testcases/general/inherit_function.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/inherit_function.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a94f799
--- /dev/null
+++ b/pkg/front_end/testcases/general/inherit_function.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+class A implements Function {}
+
+class B extends Function {}
+
+class C extends Object with Function {}
+
+class D = Object with Function;
+main() {}
diff --git a/pkg/front_end/testcases/general/interface_conflict.dart.textual_outline.expect b/pkg/front_end/testcases/general/interface_conflict.dart.textual_outline.expect
new file mode 100644
index 0000000..669b460
--- /dev/null
+++ b/pkg/front_end/testcases/general/interface_conflict.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+class A {
+ int get n => 1;
+}
+
+class B {
+ double get n => 2.0;
+}
+
+abstract class C implements A, B {}
+
+abstract class D implements C {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/interface_conflict.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/interface_conflict.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d216e6b
--- /dev/null
+++ b/pkg/front_end/testcases/general/interface_conflict.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+abstract class C implements A, B {}
+
+abstract class D implements C {}
+
+class A {
+ int get n => 1;
+}
+
+class B {
+ double get n => 2.0;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/interface_contravariant_from_class.dart.textual_outline.expect b/pkg/front_end/testcases/general/interface_contravariant_from_class.dart.textual_outline.expect
new file mode 100644
index 0000000..fc2a60f
--- /dev/null
+++ b/pkg/front_end/testcases/general/interface_contravariant_from_class.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+typedef void F<T>(T t);
+
+class B<T> {
+ T f(int x) {}
+}
+
+abstract class I<T> {
+ T f(Object x);
+}
+
+abstract class C<T> extends B<F<T>> implements I<F<T>> {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/interface_contravariant_from_class.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/interface_contravariant_from_class.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1269acd
--- /dev/null
+++ b/pkg/front_end/testcases/general/interface_contravariant_from_class.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+library test;
+
+abstract class C<T> extends B<F<T>> implements I<F<T>> {}
+
+abstract class I<T> {
+ T f(Object x);
+}
+
+class B<T> {
+ T f(int x) {}
+}
+
+typedef void F<T>(T t);
+void main() {}
diff --git a/pkg/front_end/testcases/general/interface_covariantImpl_from_class.dart.textual_outline.expect b/pkg/front_end/testcases/general/interface_covariantImpl_from_class.dart.textual_outline.expect
new file mode 100644
index 0000000..aec0365
--- /dev/null
+++ b/pkg/front_end/testcases/general/interface_covariantImpl_from_class.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+typedef void F<T>(T t);
+
+class B<T> {
+ void f(F<T> x, int y) {}
+}
+
+abstract class I<T> {
+ void f(F<T> x, Object y);
+}
+
+abstract class C<T> extends B<F<T>> implements I<F<T>> {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/interface_covariantImpl_from_class.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/interface_covariantImpl_from_class.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..033ea81
--- /dev/null
+++ b/pkg/front_end/testcases/general/interface_covariantImpl_from_class.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+library test;
+
+abstract class C<T> extends B<F<T>> implements I<F<T>> {}
+
+abstract class I<T> {
+ void f(F<T> x, Object y);
+}
+
+class B<T> {
+ void f(F<T> x, int y) {}
+}
+
+typedef void F<T>(T t);
+void main() {}
diff --git a/pkg/front_end/testcases/general/interface_covariantInterface_from_class.dart.textual_outline.expect b/pkg/front_end/testcases/general/interface_covariantInterface_from_class.dart.textual_outline.expect
new file mode 100644
index 0000000..203e8cd
--- /dev/null
+++ b/pkg/front_end/testcases/general/interface_covariantInterface_from_class.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+library test;
+
+typedef void F<T>(T t);
+
+abstract class A<T> {
+ void f(T x, int y);
+}
+
+class B<T> implements A<F<T>> {
+ void f(F<T> x, int y) {}
+}
+
+abstract class I<T> implements A<F<T>> {
+ void f(F<T> x, Object y);
+}
+
+abstract class C<T> extends B<F<T>> implements I<F<T>> {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/interface_covariantInterface_from_class.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/interface_covariantInterface_from_class.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4615ebb
--- /dev/null
+++ b/pkg/front_end/testcases/general/interface_covariantInterface_from_class.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+library test;
+
+abstract class A<T> {
+ void f(T x, int y);
+}
+
+abstract class C<T> extends B<F<T>> implements I<F<T>> {}
+
+abstract class I<T> implements A<F<T>> {
+ void f(F<T> x, Object y);
+}
+
+class B<T> implements A<F<T>> {
+ void f(F<T> x, int y) {}
+}
+
+typedef void F<T>(T t);
+void main() {}
diff --git a/pkg/front_end/testcases/general/invalid_assignment.dart.textual_outline.expect b/pkg/front_end/testcases/general/invalid_assignment.dart.textual_outline.expect
new file mode 100644
index 0000000..60f20bb
--- /dev/null
+++ b/pkg/front_end/testcases/general/invalid_assignment.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class A {
+ String operator +(int i) => '';
+}
+
+test(int i, String s, A a) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/invalid_assignment.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/invalid_assignment.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a50d569
--- /dev/null
+++ b/pkg/front_end/testcases/general/invalid_assignment.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class A {
+ String operator +(int i) => '';
+}
+
+main() {}
+test(int i, String s, A a) {}
diff --git a/pkg/front_end/testcases/general/invalid_cast.dart.textual_outline.expect b/pkg/front_end/testcases/general/invalid_cast.dart.textual_outline.expect
new file mode 100644
index 0000000..225b633
--- /dev/null
+++ b/pkg/front_end/testcases/general/invalid_cast.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+class C {
+ C();
+ factory C.fact() => null;
+ factory C.fact2() = D;
+ C.nonFact();
+ C.nonFact2() : this.nonFact();
+ static void staticFunction(int i) {}
+}
+
+class D extends C {}
+
+void topLevelFunction(int i) {}
+bad() {}
+ok() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/invalid_cast.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/invalid_cast.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..45d7ffc
--- /dev/null
+++ b/pkg/front_end/testcases/general/invalid_cast.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+bad() {}
+
+class C {
+ C();
+ C.nonFact();
+ C.nonFact2() : this.nonFact();
+ factory C.fact() => null;
+ factory C.fact2() = D;
+ static void staticFunction(int i) {}
+}
+
+class D extends C {}
+
+main() {}
+ok() {}
+void topLevelFunction(int i) {}
diff --git a/pkg/front_end/testcases/general/invalid_operator.dart.textual_outline.expect b/pkg/front_end/testcases/general/invalid_operator.dart.textual_outline.expect
new file mode 100644
index 0000000..6f6cae0
--- /dev/null
+++ b/pkg/front_end/testcases/general/invalid_operator.dart.textual_outline.expect
@@ -0,0 +1,147 @@
+class Operators1 {
+ operator ==() => true;
+ operator <() => true;
+ operator >() => true;
+ operator <=() => true;
+ operator >=() => true;
+ operator +() => true;
+ operator /() => true;
+ operator ~/() => true;
+ operator *() => true;
+ operator %() => true;
+ operator |() => true;
+ operator ^() => true;
+ operator &() => true;
+ operator <<() => true;
+ operator >>() => true;
+ operator []=(a, b, c) => true;
+ operator []() => true;
+ operator ~(a) => true;
+}
+class Operators2 {
+ operator ==(a, b) => true;
+ operator <(a, b) => true;
+ operator >(a, b) => true;
+ operator <=(a, b) => true;
+ operator >=(a, b) => true;
+ operator -(a, b) => true;
+ operator +(a, b) => true;
+ operator /(a, b) => true;
+ operator ~/(a, b) => true;
+ operator *(a, b) => true;
+ operator %(a, b) => true;
+ operator |(a, b) => true;
+ operator ^(a, b) => true;
+ operator &(a, b) => true;
+ operator <<(a, b) => true;
+ operator >>(a, b) => true;
+ operator []=(a, b, c) => true;
+ operator [](a, b) => true;
+ operator ~(a, b) => true;
+}
+class Operators3 {
+ operator ==([a]) => true;
+ operator <([a]) => true;
+ operator >([a]) => true;
+ operator <=([a]) => true;
+ operator >=([a]) => true;
+ operator -([a]) => true;
+ operator +([a]) => true;
+ operator /([a]) => true;
+ operator ~/([a]) => true;
+ operator *([a]) => true;
+ operator %([a]) => true;
+ operator |([a]) => true;
+ operator ^([a]) => true;
+ operator &([a]) => true;
+ operator <<([a]) => true;
+ operator >>([a]) => true;
+ operator []=([a, b]) => true;
+ operator []([a]) => true;
+ operator ~([a]) => true;
+}
+class Operators4 {
+ operator ==({a}) => true;
+ operator <({a}) => true;
+ operator >({a}) => true;
+ operator <=({a}) => true;
+ operator >=({a}) => true;
+ operator -({a}) => true;
+ operator +({a}) => true;
+ operator /({a}) => true;
+ operator ~/({a}) => true;
+ operator *({a}) => true;
+ operator %({a}) => true;
+ operator |({a}) => true;
+ operator ^({a}) => true;
+ operator &({a}) => true;
+ operator <<({a}) => true;
+ operator >>({a}) => true;
+ operator []=({a, b}) => true;
+ operator []({a}) => true;
+ operator ~({a}) => true;
+}
+class Operators5 {
+ operator ==(a, [b]) => true;
+ operator <(a, [b]) => true;
+ operator >(a, [b]) => true;
+ operator <=(a, [b]) => true;
+ operator >=(a, [b]) => true;
+ operator -(a, [b]) => true;
+ operator +(a, [b]) => true;
+ operator /(a, [b]) => true;
+ operator ~/(a, [b]) => true;
+ operator *(a, [b]) => true;
+ operator %(a, [b]) => true;
+ operator |(a, [b]) => true;
+ operator ^(a, [b]) => true;
+ operator &(a, [b]) => true;
+ operator <<(a, [b]) => true;
+ operator >>(a, [b]) => true;
+ operator []=(a, b, [c]) => true;
+ operator [](a, [b]) => true;
+ operator ~(a, [b]) => true;
+}
+class Operators6 {
+ operator ==(a, {b}) => true;
+ operator <(a, {b}) => true;
+ operator >(a, {b}) => true;
+ operator <=(a, {b}) => true;
+ operator >=(a, {b}) => true;
+ operator -(a, {b}) => true;
+ operator +(a, {b}) => true;
+ operator /(a, {b}) => true;
+ operator ~/(a, {b}) => true;
+ operator *(a, {b}) => true;
+ operator %(a, {b}) => true;
+ operator |(a, {b}) => true;
+ operator ^(a, {b}) => true;
+ operator &(a, {b}) => true;
+ operator <<(a, {b}) => true;
+ operator >>(a, {b}) => true;
+ operator []=(a, b, {c}) => true;
+ operator [](a, {b}) => true;
+ operator ~(a, {b}) => true;
+}
+class Operators7 {
+ operator ==<T>(a) => true;
+ operator ><T>(a) => true;
+ operator <=<T>(a) => true;
+ operator >=<T>(a) => true;
+ operator -<T>() => true;
+ operator -<T>(a) => true;
+ operator +<T>(a) => true;
+ operator /<T>(a) => true;
+ operator ~/<T>(a) => true;
+ operator *<T>(a) => true;
+ operator %<T>(a) => true;
+ operator |<T>(a) => true;
+ operator ^<T>(a) => true;
+ operator &<T>(a) => true;
+ operator <<<T>(a) => true;
+ operator >><T>(a) => true;
+ operator []=<T>(a, b) => true;
+ operator []<T>(a) => true;
+ operator ~<T>() => true;
+}
+main() { }
diff --git a/pkg/front_end/testcases/general/invalid_operator2.dart.textual_outline.expect b/pkg/front_end/testcases/general/invalid_operator2.dart.textual_outline.expect
new file mode 100644
index 0000000..5f489fc
--- /dev/null
+++ b/pkg/front_end/testcases/general/invalid_operator2.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class Operators7 {
+ operator <<( ){ }
+ Toperator>(a) => true;
+}
+main() { }
diff --git a/pkg/front_end/testcases/general/invalid_type.dart.textual_outline.expect b/pkg/front_end/testcases/general/invalid_type.dart.textual_outline.expect
new file mode 100644
index 0000000..6cef1e5
--- /dev/null
+++ b/pkg/front_end/testcases/general/invalid_type.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class C {
+ static foo() {}
+}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/invalid_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/invalid_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a02ed16
--- /dev/null
+++ b/pkg/front_end/testcases/general/invalid_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class C {
+ static foo() {}
+}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/invocations.dart.textual_outline.expect b/pkg/front_end/testcases/general/invocations.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/invocations.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/invocations.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/invocations.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/invocations.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/issue129167943.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue129167943.dart.textual_outline.expect
new file mode 100644
index 0000000..2d33b0a
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue129167943.dart.textual_outline.expect
@@ -0,0 +1,55 @@
+abstract class A {}
+
+abstract class B {
+ void foo(num x);
+}
+
+abstract class C implements B {
+ void foo(covariant int x);
+}
+
+abstract class D1 implements A, C, B {
+ void foo(covariant int x);
+}
+
+class D2 implements A, C, B {
+ void foo(covariant int x) {}
+}
+
+abstract class D3 implements A, C, B {}
+
+abstract class D4 implements A, C, B {
+ void foo(int x);
+}
+
+abstract class D5 implements A, C, B {
+ void foo(num x);
+}
+
+abstract class E {
+ void set foo(num x);
+}
+
+abstract class G implements E {
+ void set foo(covariant int x);
+}
+
+abstract class H1 implements A, E, G {
+ void set foo(covariant int x);
+}
+
+class H2 implements A, E, G {
+ void set foo(covariant int x) {}
+}
+
+abstract class H3 implements A, E, G {}
+
+abstract class H4 implements A, E, G {
+ void set foo(int x);
+}
+
+abstract class H5 implements A, E, G {
+ void set foo(num x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue129167943.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue129167943.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3d5bb93
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue129167943.dart.textual_outline_modelled.expect
@@ -0,0 +1,55 @@
+abstract class A {}
+
+abstract class B {
+ void foo(num x);
+}
+
+abstract class C implements B {
+ void foo(covariant int x);
+}
+
+abstract class D1 implements A, C, B {
+ void foo(covariant int x);
+}
+
+abstract class D3 implements A, C, B {}
+
+abstract class D4 implements A, C, B {
+ void foo(int x);
+}
+
+abstract class D5 implements A, C, B {
+ void foo(num x);
+}
+
+abstract class E {
+ void set foo(num x);
+}
+
+abstract class G implements E {
+ void set foo(covariant int x);
+}
+
+abstract class H1 implements A, E, G {
+ void set foo(covariant int x);
+}
+
+abstract class H3 implements A, E, G {}
+
+abstract class H4 implements A, E, G {
+ void set foo(int x);
+}
+
+abstract class H5 implements A, E, G {
+ void set foo(num x);
+}
+
+class D2 implements A, C, B {
+ void foo(covariant int x) {}
+}
+
+class H2 implements A, E, G {
+ void set foo(covariant int x) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue34515.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue34515.dart.textual_outline.expect
new file mode 100644
index 0000000..0d74c15
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue34515.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import "issue34515_lib1.dart";
+import "issue34515_lib2.dart";
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/issue34515.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue34515.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..608fcf1
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue34515.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import "issue34515_lib1.dart";
+import "issue34515_lib2.dart";
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/general/issue34899.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue34899.dart.textual_outline.expect
new file mode 100644
index 0000000..18c8795
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue34899.dart.textual_outline.expect
@@ -0,0 +1,20 @@
+class Foo<T> {
+ final Future<dynamic> Function() quux;
+ T t;
+ Foo(this.quux, this.t);
+ Future<T> call() => quux().then<T>((_) => t);
+}
+
+class Bar {
+ Foo<Baz> qux;
+ Future<void> quuz() =>
+ qux().then((baz) => corge(baz)).then((grault) => garply(grault));
+ Grault corge(Baz baz) => null;
+ void garply(Grault grault) {}
+}
+
+class Baz {}
+
+class Grault {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue34899.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue34899.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1b2af4b
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue34899.dart.textual_outline_modelled.expect
@@ -0,0 +1,20 @@
+class Bar {
+ Foo<Baz> qux;
+ Future<void> quuz() =>
+ qux().then((baz) => corge(baz)).then((grault) => garply(grault));
+ Grault corge(Baz baz) => null;
+ void garply(Grault grault) {}
+}
+
+class Baz {}
+
+class Foo<T> {
+ Foo(this.quux, this.t);
+ Future<T> call() => quux().then<T>((_) => t);
+ T t;
+ final Future<dynamic> Function() quux;
+}
+
+class Grault {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue35875.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue35875.dart.textual_outline.expect
new file mode 100644
index 0000000..5552256
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue35875.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class A {
+ int a;
+ A(int a) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue35875.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue35875.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a56bd0f
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue35875.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class A {
+ A(int a) {}
+ int a;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue37027.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue37027.dart.textual_outline.expect
new file mode 100644
index 0000000..40abec7
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue37027.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class C {
+ final Set<int> s;
+ C(List<int> ell)
+ : s = {
+ for (var e in ell)
+ if (e.isOdd) 2 * e
+ };
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue37027.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue37027.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4a6b9aa
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue37027.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+class C {
+ C(List<int> ell)
+ : s = {
+ for (var e in ell)
+ if (e.isOdd) 2 * e
+ };
+ final Set<int> s;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue37381.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue37381.dart.textual_outline.expect
new file mode 100644
index 0000000..0e78f9c
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue37381.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class A<X> {
+ R f<R>(R Function<X>(A<X>) f) => f<X>(this);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue37381.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue37381.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0e78f9c
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue37381.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+class A<X> {
+ R f<R>(R Function<X>(A<X>) f) => f<X>(this);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue37776.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue37776.dart.textual_outline.expect
new file mode 100644
index 0000000..fe9bbfe
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue37776.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class X {
+ const X.foo();
+}
+
+class X {
+ const X.foo();
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/issue37776.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue37776.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fe9bbfe
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue37776.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class X {
+ const X.foo();
+}
+
+class X {
+ const X.foo();
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/issue38812.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue38812.dart.textual_outline.expect
new file mode 100644
index 0000000..f69b6fc
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue38812.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+typedef G<X> = void Function();
+
+class A<X extends G<A<Y, X>>, Y extends G<A<X, Y>>> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue38812.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue38812.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f0058f6
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue38812.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+class A<X extends G<A<Y, X>>, Y extends G<A<X, Y>>> {}
+
+main() {}
+typedef G<X> = void Function();
diff --git a/pkg/front_end/testcases/general/issue38938.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue38938.dart.textual_outline.expect
new file mode 100644
index 0000000..82bf141
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue38938.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class A {
+ int v;
+ int v;
+ A(this.v);
+ A.second();
+}
diff --git a/pkg/front_end/testcases/general/issue38938.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue38938.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fc11ff3
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue38938.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class A {
+ A(this.v);
+ A.second();
+ int v;
+ int v;
+}
diff --git a/pkg/front_end/testcases/general/issue38943.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue38943.dart.textual_outline.expect
new file mode 100644
index 0000000..f78c92f
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue38943.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class D<X extends void Function()> {
+ factory D.foo() => new D._();
+ D._() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue38943.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue38943.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..256c973
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue38943.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class D<X extends void Function()> {
+ D._() {}
+ factory D.foo() => new D._();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue38944.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue38944.dart.textual_outline.expect
new file mode 100644
index 0000000..279bc70
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue38944.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+class A<Q> {}
+
+class B<X> extends Object with A<void Function<Y extends X>()> {}
diff --git a/pkg/front_end/testcases/general/issue38944.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue38944.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..279bc70
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue38944.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+class A<Q> {}
+
+class B<X> extends Object with A<void Function<Y extends X>()> {}
diff --git a/pkg/front_end/testcases/general/issue38961.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue38961.dart.textual_outline.expect
new file mode 100644
index 0000000..f38f3d3
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue38961.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class C {
+ dynamic x = this;
+ var x = this;
+}
diff --git a/pkg/front_end/testcases/general/issue38961.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue38961.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f38f3d3
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue38961.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+class C {
+ dynamic x = this;
+ var x = this;
+}
diff --git a/pkg/front_end/testcases/general/issue39344.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue39344.dart.textual_outline.expect
new file mode 100644
index 0000000..4b6675e
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue39344.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+class A {}
+
+class B extends A {}
+
+List<B> xs;
+List<List<B>> xss;
+
+class Class<T extends A> {
+ void method1a(T t) {}
+ void method1b(T t) {}
+ void method2a(T t) {}
+ void method2b(T t) {}
+}
+
+void main() {}
+void errors() {}
+void throws(void Function() f) {}
diff --git a/pkg/front_end/testcases/general/issue39344.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue39344.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fc29cea
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue39344.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+List<B> xs;
+List<List<B>> xss;
+
+class A {}
+
+class B extends A {}
+
+class Class<T extends A> {
+ void method1a(T t) {}
+ void method1b(T t) {}
+ void method2a(T t) {}
+ void method2b(T t) {}
+}
+
+void errors() {}
+void main() {}
+void throws(void Function() f) {}
diff --git a/pkg/front_end/testcases/general/issue39421.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue39421.dart.textual_outline.expect
new file mode 100644
index 0000000..8ac9791
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue39421.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+class A {}
+
+class A {}
+
+class B {
+ foo(List<Null> a) {}
+}
+
+class C extends B {
+ foo(List<A> a) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue39421.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue39421.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8ac9791
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue39421.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+class A {}
+
+class A {}
+
+class B {
+ foo(List<Null> a) {}
+}
+
+class C extends B {
+ foo(List<A> a) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue39817.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue39817.dart.textual_outline.expect
new file mode 100644
index 0000000..d530fa8
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue39817.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/issue39817.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue39817.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d530fa8
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue39817.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/issue40242.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue40242.dart.textual_outline.expect
new file mode 100644
index 0000000..3071c2b
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue40242.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class C {
+}
+extension E ;
+on C (){ }
+errors() { }
+main() { }
diff --git a/pkg/front_end/testcases/general/issue40428.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue40428.dart.textual_outline.expect
new file mode 100644
index 0000000..4508570
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue40428.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+abstract class SuperClass1 {
+ final String value;
+ SuperClass1(this.value);
+}
+
+abstract class SuperClass2 {
+ final String value;
+ SuperClass2(String i) : value = i;
+}
+
+class Mixin {}
+
+class NamedMixin1 = SuperClass1 with Mixin;
+class NamedMixin2 = SuperClass2 with Mixin;
+void main() {}
+errors() {}
diff --git a/pkg/front_end/testcases/general/issue40428.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue40428.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b9d7f4f
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue40428.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+abstract class SuperClass1 {
+ SuperClass1(this.value);
+ final String value;
+}
+
+abstract class SuperClass2 {
+ SuperClass2(String i) : value = i;
+ final String value;
+}
+
+class Mixin {}
+
+class NamedMixin1 = SuperClass1 with Mixin;
+class NamedMixin2 = SuperClass2 with Mixin;
+errors() {}
+void main() {}
diff --git a/pkg/front_end/testcases/general/issue40662.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue40662.dart.textual_outline.expect
new file mode 100644
index 0000000..422ab5e
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue40662.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+bar(int a, List<int> b) {}
+foo(int x) async => bar(x - 1, x != null ? [x + 1, x + 2, await null] : null);
+void main() async => await foo(0);
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/general/issue40662.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue40662.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..19a1c91
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue40662.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+bar(int a, List<int> b) {}
+expect(expected, actual) {}
+foo(int x) async => bar(x - 1, x != null ? [x + 1, x + 2, await null] : null);
+void main() async => await foo(0);
diff --git a/pkg/front_end/testcases/general/issue40744.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue40744.dart.textual_outline.expect
new file mode 100644
index 0000000..dd27ae6
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue40744.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+const generatorConfigDefaultJson = <String, dynamic>{'a': 1};
+void helper(Map<String, dynamic> input) {}
+void main() {}
diff --git a/pkg/front_end/testcases/general/issue40744.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue40744.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..dd27ae6
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue40744.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+const generatorConfigDefaultJson = <String, dynamic>{'a': 1};
+void helper(Map<String, dynamic> input) {}
+void main() {}
diff --git a/pkg/front_end/testcases/general/issue41070.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue41070.dart.textual_outline.expect
new file mode 100644
index 0000000..6b9ed3f
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue41070.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+abstract class Mixin {}
+
+class Base {
+ final int x;
+ const Base(this.x);
+}
+
+class Application = Base with Mixin;
+main() {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/general/issue41070.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue41070.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0d6b4da
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue41070.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+abstract class Mixin {}
+
+class Base {
+ const Base(this.x);
+ final int x;
+}
+
+class Application = Base with Mixin;
+expect(expected, actual) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/issue41210a.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue41210a.dart.textual_outline.expect
new file mode 100644
index 0000000..8fc1032
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue41210a.dart.textual_outline.expect
@@ -0,0 +1,23 @@
+abstract class Interface {
+ String method(num i);
+}
+
+abstract class Interface2 {
+ String method(covariant int i);
+}
+
+mixin A implements Interface {
+ String method(num i, {String s = "hello"}) => s;
+}
+
+abstract class B implements Interface {
+ String method(num i);
+}
+
+class C with A, B {}
+
+abstract class D implements Interface, Interface2 {}
+
+class E with A, D {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue41210a.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue41210a.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6ec25da
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue41210a.dart.textual_outline_modelled.expect
@@ -0,0 +1,22 @@
+abstract class B implements Interface {
+ String method(num i);
+}
+
+abstract class D implements Interface, Interface2 {}
+
+abstract class Interface {
+ String method(num i);
+}
+
+abstract class Interface2 {
+ String method(covariant int i);
+}
+
+class C with A, B {}
+
+class E with A, D {}
+
+main() {}
+mixin A implements Interface {
+ String method(num i, {String s = "hello"}) => s;
+}
diff --git a/pkg/front_end/testcases/general/issue41210b/issue41210.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue41210b/issue41210.dart.textual_outline.expect
new file mode 100644
index 0000000..7354b67
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue41210b/issue41210.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+import 'issue41210_lib.dart';
+
+class C with A, B {}
+
+class E with A, D {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue41210b/issue41210.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue41210b/issue41210.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7354b67
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue41210b/issue41210.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+import 'issue41210_lib.dart';
+
+class C with A, B {}
+
+class E with A, D {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/literals.dart.textual_outline.expect b/pkg/front_end/testcases/general/literals.dart.textual_outline.expect
new file mode 100644
index 0000000..8732e5c8
--- /dev/null
+++ b/pkg/front_end/testcases/general/literals.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+testString() {}
+testInt() {}
+testBool() {}
+testDouble() {}
+testNull() {}
+testList() {}
+testMap() {}
+testSymbol() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/literals.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/literals.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e45ac05
--- /dev/null
+++ b/pkg/front_end/testcases/general/literals.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+main() {}
+testBool() {}
+testDouble() {}
+testInt() {}
+testList() {}
+testMap() {}
+testNull() {}
+testString() {}
+testSymbol() {}
diff --git a/pkg/front_end/testcases/general/local_generic_function.dart.textual_outline.expect b/pkg/front_end/testcases/general/local_generic_function.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/local_generic_function.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/local_generic_function.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/local_generic_function.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/local_generic_function.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/long_chain_of_typedefs.dart.textual_outline.expect b/pkg/front_end/testcases/general/long_chain_of_typedefs.dart.textual_outline.expect
new file mode 100644
index 0000000..22729bf
--- /dev/null
+++ b/pkg/front_end/testcases/general/long_chain_of_typedefs.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+typedef Foo01<X, Y, Z> = void Function(Null);
+typedef Foo02<X, Y, Z> = void Function(Foo01<X, Y, Z>);
+typedef Foo03<X, Y, Z> = void Function(Foo02<X, Y, Z>);
+typedef Foo04<X, Y, Z> = void Function(Foo03<X, Y, Z>);
+typedef Foo05<X, Y, Z> = void Function(Foo04<X, Y, Z>);
+typedef Foo06<X, Y, Z> = void Function(Foo05<X, Y, Z>);
+typedef Foo07<X, Y, Z> = void Function(Foo06<X, Y, Z>);
+typedef Foo08<X, Y, Z> = void Function(Foo07<X, Y, Z>);
+typedef Foo09<X, Y, Z> = void Function(Foo08<X, Y, Z>);
+typedef Foo10<X, Y, Z> = void Function(Foo09<X, Y, Z>);
+typedef Foo11<X, Y, Z> = void Function(Foo10<X, Y, Z>);
+typedef Foo12<X, Y, Z> = void Function(Foo11<X, Y, Z>);
+typedef Foo13<X, Y, Z> = void Function(Foo12<X, Y, Z>);
+typedef Foo14<X, Y, Z> = void Function(Foo13<X, Y, Z>);
+typedef Foo15<X, Y, Z> = void Function(Foo14<X, Y, Z>);
+typedef Foo16<X, Y, Z> = void Function(Foo15<X, Y, Z>);
+typedef Foo17<X, Y, Z> = void Function(Foo16<X, Y, Z>);
+typedef Foo18<X, Y, Z> = void Function(Foo17<X, Y, Z>);
+typedef Foo19<X, Y, Z> = void Function(Foo18<X, Y, Z>);
+typedef Foo20<X, Y, Z> = void Function(Foo19<X, Y, Z>);
+main() {}
diff --git a/pkg/front_end/testcases/general/long_chain_of_typedefs.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/long_chain_of_typedefs.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..20e1848
--- /dev/null
+++ b/pkg/front_end/testcases/general/long_chain_of_typedefs.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+main() {}
+typedef Foo01<X, Y, Z> = void Function(Null);
+typedef Foo02<X, Y, Z> = void Function(Foo01<X, Y, Z>);
+typedef Foo03<X, Y, Z> = void Function(Foo02<X, Y, Z>);
+typedef Foo04<X, Y, Z> = void Function(Foo03<X, Y, Z>);
+typedef Foo05<X, Y, Z> = void Function(Foo04<X, Y, Z>);
+typedef Foo06<X, Y, Z> = void Function(Foo05<X, Y, Z>);
+typedef Foo07<X, Y, Z> = void Function(Foo06<X, Y, Z>);
+typedef Foo08<X, Y, Z> = void Function(Foo07<X, Y, Z>);
+typedef Foo09<X, Y, Z> = void Function(Foo08<X, Y, Z>);
+typedef Foo10<X, Y, Z> = void Function(Foo09<X, Y, Z>);
+typedef Foo11<X, Y, Z> = void Function(Foo10<X, Y, Z>);
+typedef Foo12<X, Y, Z> = void Function(Foo11<X, Y, Z>);
+typedef Foo13<X, Y, Z> = void Function(Foo12<X, Y, Z>);
+typedef Foo14<X, Y, Z> = void Function(Foo13<X, Y, Z>);
+typedef Foo15<X, Y, Z> = void Function(Foo14<X, Y, Z>);
+typedef Foo16<X, Y, Z> = void Function(Foo15<X, Y, Z>);
+typedef Foo17<X, Y, Z> = void Function(Foo16<X, Y, Z>);
+typedef Foo18<X, Y, Z> = void Function(Foo17<X, Y, Z>);
+typedef Foo19<X, Y, Z> = void Function(Foo18<X, Y, Z>);
+typedef Foo20<X, Y, Z> = void Function(Foo19<X, Y, Z>);
diff --git a/pkg/front_end/testcases/general/magic_const.dart.textual_outline.expect b/pkg/front_end/testcases/general/magic_const.dart.textual_outline.expect
new file mode 100644
index 0000000..63982d2
--- /dev/null
+++ b/pkg/front_end/testcases/general/magic_const.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class Constant {
+ const Constant();
+}
+
+class NotConstant {}
+
+foo({a: Constant(), b: Constant(), c: []}) {}
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/magic_const.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/magic_const.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..98f38df
--- /dev/null
+++ b/pkg/front_end/testcases/general/magic_const.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class Constant {
+ const Constant();
+}
+
+class NotConstant {}
+
+foo({a: Constant(), b: Constant(), c: []}) {}
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/many_errors.dart.textual_outline.expect b/pkg/front_end/testcases/general/many_errors.dart.textual_outline.expect
new file mode 100644
index 0000000..76b7c69
--- /dev/null
+++ b/pkg/front_end/testcases/general/many_errors.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+class A {
+ final x = null;
+ const A.named1() sync* { }
+ const A.named2() : x = new Object();
+}
+external foo(String x) { }
+class B {
+}
+class C {
+ B b;
+}
+abstract class AbstractClass {
+ const AbstractClass.id();
+}
+m() { }
+main() { }
diff --git a/pkg/front_end/testcases/general/map.dart.textual_outline.expect b/pkg/front_end/testcases/general/map.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/map.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/map.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/map.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/map.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/metadata_enum.dart.textual_outline.expect b/pkg/front_end/testcases/general/metadata_enum.dart.textual_outline.expect
new file mode 100644
index 0000000..ab7b226
--- /dev/null
+++ b/pkg/front_end/testcases/general/metadata_enum.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+const a = null;
+@a
+enum E { E1, E2, E3 }
+main() {}
diff --git a/pkg/front_end/testcases/general/metadata_enum.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/metadata_enum.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6cb51de
--- /dev/null
+++ b/pkg/front_end/testcases/general/metadata_enum.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+@a
+enum E { E1, E2, E3 }
+const a = null;
+main() {}
diff --git a/pkg/front_end/testcases/general/metadata_named_mixin_application.dart.textual_outline.expect b/pkg/front_end/testcases/general/metadata_named_mixin_application.dart.textual_outline.expect
new file mode 100644
index 0000000..525a405
--- /dev/null
+++ b/pkg/front_end/testcases/general/metadata_named_mixin_application.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+const a = null;
+@a
+class C = D with E;
+
+class D {}
+
+class E {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/metadata_named_mixin_application.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/metadata_named_mixin_application.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..77307d2
--- /dev/null
+++ b/pkg/front_end/testcases/general/metadata_named_mixin_application.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+@a
+const a = null;
+class C = D with E;
+
+class D {}
+
+class E {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/micro.dart.textual_outline.expect b/pkg/front_end/testcases/general/micro.dart.textual_outline.expect
new file mode 100644
index 0000000..1c27a80
--- /dev/null
+++ b/pkg/front_end/testcases/general/micro.dart.textual_outline.expect
@@ -0,0 +1,42 @@
+staticMethod() {}
+
+class Foo {
+ instanceMethod() {}
+}
+
+external bool externalStatic();
+
+abstract class ExternalValue {}
+
+abstract class Bar {
+ ExternalValue externalInstanceMethod();
+}
+
+external Bar createBar();
+
+class Box {
+ var field;
+}
+
+stringArgument(x) {}
+intArgument(x) {}
+
+class FinalBox {
+ final finalField;
+ FinalBox(this.finalField);
+}
+
+class SubFinalBox extends FinalBox {
+ SubFinalBox(value) : super(value);
+}
+
+class DynamicReceiver1 {
+ dynamicallyCalled(x) {}
+}
+
+class DynamicReceiver2 {
+ dynamicallyCalled(x) {}
+}
+
+void makeDynamicCall(receiver) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/micro.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/micro.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0ec1840
--- /dev/null
+++ b/pkg/front_end/testcases/general/micro.dart.textual_outline_modelled.expect
@@ -0,0 +1,38 @@
+abstract class Bar {
+ ExternalValue externalInstanceMethod();
+}
+
+abstract class ExternalValue {}
+
+class Box {
+ var field;
+}
+
+class DynamicReceiver1 {
+ dynamicallyCalled(x) {}
+}
+
+class DynamicReceiver2 {
+ dynamicallyCalled(x) {}
+}
+
+class FinalBox {
+ FinalBox(this.finalField);
+ final finalField;
+}
+
+class Foo {
+ instanceMethod() {}
+}
+
+class SubFinalBox extends FinalBox {
+ SubFinalBox(value) : super(value);
+}
+
+external Bar createBar();
+external bool externalStatic();
+intArgument(x) {}
+main() {}
+staticMethod() {}
+stringArgument(x) {}
+void makeDynamicCall(receiver) {}
diff --git a/pkg/front_end/testcases/general/minimum_int.dart.textual_outline.expect b/pkg/front_end/testcases/general/minimum_int.dart.textual_outline.expect
new file mode 100644
index 0000000..4b5a61c
--- /dev/null
+++ b/pkg/front_end/testcases/general/minimum_int.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() => print(-9223372036854775808);
diff --git a/pkg/front_end/testcases/general/minimum_int.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/minimum_int.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4b5a61c
--- /dev/null
+++ b/pkg/front_end/testcases/general/minimum_int.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() => print(-9223372036854775808);
diff --git a/pkg/front_end/testcases/general/missing_constructor.dart.textual_outline.expect b/pkg/front_end/testcases/general/missing_constructor.dart.textual_outline.expect
new file mode 100644
index 0000000..021aaf9
--- /dev/null
+++ b/pkg/front_end/testcases/general/missing_constructor.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+class Super {
+ Super._();
+}
+
+class Sub extends Super {
+ Sub() : super();
+ Sub.foo() : super.foo();
+}
+
+class Bad {
+ Bad.foo() : this();
+ Bad.bar() : this.baz();
+}
+
+class M {}
+
+class MixinApplication extends Super with M {
+ MixinApplication() : super();
+ MixinApplication.foo() : super.foo();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/missing_constructor.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/missing_constructor.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..44085f9
--- /dev/null
+++ b/pkg/front_end/testcases/general/missing_constructor.dart.textual_outline_modelled.expect
@@ -0,0 +1,22 @@
+class Bad {
+ Bad.bar() : this.baz();
+ Bad.foo() : this();
+}
+
+class M {}
+
+class MixinApplication extends Super with M {
+ MixinApplication() : super();
+ MixinApplication.foo() : super.foo();
+}
+
+class Sub extends Super {
+ Sub() : super();
+ Sub.foo() : super.foo();
+}
+
+class Super {
+ Super._();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/missing_toplevel.dart.textual_outline.expect b/pkg/front_end/testcases/general/missing_toplevel.dart.textual_outline.expect
new file mode 100644
index 0000000..ee318d7
--- /dev/null
+++ b/pkg/front_end/testcases/general/missing_toplevel.dart.textual_outline.expect
@@ -0,0 +1,27 @@
+class EmptyClass {}
+
+var emptyClass = new EmptyClass();
+
+class ClassWithProperty {
+ EmptyClass property;
+}
+
+var classWithProperty = new ClassWithProperty();
+
+class ClassWithIndexSet {
+ operator []=(int index, int value) {}
+}
+
+var classWithIndexSet = new ClassWithIndexSet();
+
+class ClassWithIndexGet {
+ int operator [](int index) => 42;
+}
+
+var classWithIndexGet = new ClassWithIndexGet();
+var missingBinary = classWithProperty.property += 2;
+var missingIndexGet = classWithIndexSet[0] ??= 2;
+var missingIndexSet = classWithIndexGet[0] ??= 2;
+var missingPropertyGet = emptyClass.property;
+var missingPropertySet = emptyClass.property = 42;
+main() {}
diff --git a/pkg/front_end/testcases/general/missing_toplevel.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/missing_toplevel.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c685729
--- /dev/null
+++ b/pkg/front_end/testcases/general/missing_toplevel.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+class ClassWithIndexGet {
+ int operator [](int index) => 42;
+}
+
+class ClassWithIndexSet {
+ operator []=(int index, int value) {}
+}
+
+class ClassWithProperty {
+ EmptyClass property;
+}
+
+class EmptyClass {}
+
+main() {}
+var classWithIndexGet = new ClassWithIndexGet();
+var classWithIndexSet = new ClassWithIndexSet();
+var classWithProperty = new ClassWithProperty();
+var emptyClass = new EmptyClass();
+var missingBinary = classWithProperty.property += 2;
+var missingIndexGet = classWithIndexSet[0] ??= 2;
+var missingIndexSet = classWithIndexGet[0] ??= 2;
+var missingPropertyGet = emptyClass.property;
+var missingPropertySet = emptyClass.property = 42;
diff --git a/pkg/front_end/testcases/general/mixin.dart.textual_outline.expect b/pkg/front_end/testcases/general/mixin.dart.textual_outline.expect
new file mode 100644
index 0000000..74bf0c0
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin.dart.textual_outline.expect
@@ -0,0 +1,23 @@
+class B extends Object with M1, M2 {
+ B(value);
+}
+
+abstract class M1 {
+ m() => print("M1");
+}
+
+abstract class M2 {
+ m() => print("M2");
+}
+
+class C extends Object with M1, M2 {
+ C(value);
+}
+
+abstract class G1<T> {
+ m() => print(T);
+}
+
+class D<S> extends Object with G1<S> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/mixin.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/mixin.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4fd20a5
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin.dart.textual_outline_modelled.expect
@@ -0,0 +1,23 @@
+abstract class G1<T> {
+ m() => print(T);
+}
+
+abstract class M1 {
+ m() => print("M1");
+}
+
+abstract class M2 {
+ m() => print("M2");
+}
+
+class B extends Object with M1, M2 {
+ B(value);
+}
+
+class C extends Object with M1, M2 {
+ C(value);
+}
+
+class D<S> extends Object with G1<S> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/mixin_application_inferred_parameter_type.dart.textual_outline.expect b/pkg/front_end/testcases/general/mixin_application_inferred_parameter_type.dart.textual_outline.expect
new file mode 100644
index 0000000..ee10660
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin_application_inferred_parameter_type.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class Mixin {}
+
+class Super {
+ var field = 42;
+ Super(this.field);
+}
+
+class Class = Super with Mixin;
+main() {}
+error() {}
diff --git a/pkg/front_end/testcases/general/mixin_application_inferred_parameter_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/mixin_application_inferred_parameter_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..422bc1b
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin_application_inferred_parameter_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+class Mixin {}
+
+class Super {
+ Super(this.field);
+ var field = 42;
+}
+
+class Class = Super with Mixin;
+error() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/mixin_application_override.dart.textual_outline.expect b/pkg/front_end/testcases/general/mixin_application_override.dart.textual_outline.expect
new file mode 100644
index 0000000..ee4aef8
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin_application_override.dart.textual_outline.expect
@@ -0,0 +1,34 @@
+class S {
+ foo([x]) {}
+}
+
+class M {
+ foo() {}
+}
+
+class M1 {}
+
+class M2 {}
+
+class MX {}
+
+class A0 = S with M;
+class A1 = S with M1, M;
+class A2 = S with M1, M2, M;
+class A0X = S with M, MX;
+class A1X = S with M1, M, MX;
+class A2X = S with M1, M2, M, MX;
+
+class B0 extends S with M {}
+
+class B1 extends S with M1, M {}
+
+class B2 extends S with M1, M2, M {}
+
+class B0X extends S with M, MX {}
+
+class B1X extends S with M1, M, MX {}
+
+class B2X extends S with M1, M2, M, MX {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/mixin_application_override.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/mixin_application_override.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..70161a1
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin_application_override.dart.textual_outline_modelled.expect
@@ -0,0 +1,34 @@
+class M {
+ foo() {}
+}
+
+class M1 {}
+
+class M2 {}
+
+class MX {}
+
+class S {
+ foo([x]) {}
+}
+
+class A0 = S with M;
+class A1 = S with M1, M;
+class A2 = S with M1, M2, M;
+class A0X = S with M, MX;
+class A1X = S with M1, M, MX;
+class A2X = S with M1, M2, M, MX;
+
+class B0 extends S with M {}
+
+class B0X extends S with M, MX {}
+
+class B1 extends S with M1, M {}
+
+class B1X extends S with M1, M, MX {}
+
+class B2 extends S with M1, M2, M {}
+
+class B2X extends S with M1, M2, M, MX {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/mixin_conflicts.dart.textual_outline.expect b/pkg/front_end/testcases/general/mixin_conflicts.dart.textual_outline.expect
new file mode 100644
index 0000000..5f79e28
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin_conflicts.dart.textual_outline.expect
@@ -0,0 +1,20 @@
+class M {
+ foo() {}
+}
+
+class N = Object with M;
+
+class C extends Object with N {}
+
+abstract class M2 implements M {
+ bar() {}
+}
+
+class N2 = Object with M2;
+abstract class N3 = Object with M2;
+
+class C2 extends Object with M2 {}
+
+abstract class C3 extends Object with M2 {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/mixin_conflicts.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/mixin_conflicts.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8cce55c
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin_conflicts.dart.textual_outline_modelled.expect
@@ -0,0 +1,20 @@
+class M {
+ foo() {}
+}
+
+class N = Object with M;
+
+abstract class M2 implements M {
+ bar() {}
+}
+
+class C extends Object with N {}
+
+class N2 = Object with M2;
+abstract class N3 = Object with M2;
+
+abstract class C3 extends Object with M2 {}
+
+class C2 extends Object with M2 {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/mixin_constructors_with_default_values.dart.textual_outline.expect b/pkg/front_end/testcases/general/mixin_constructors_with_default_values.dart.textual_outline.expect
new file mode 100644
index 0000000..d671b85
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin_constructors_with_default_values.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+import "package:expect/expect.dart";
+
+class C<T> {
+ String trace;
+ C({a: 0, b: T}) : trace = "a: $a, b: $b";
+}
+
+class M {}
+
+class D = C<String> with M;
+
+class E extends D {}
+
+class F extends C<int> with M {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/mixin_constructors_with_default_values.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/mixin_constructors_with_default_values.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f5c380c
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin_constructors_with_default_values.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+import "package:expect/expect.dart";
+
+class C<T> {
+ C({a: 0, b: T}) : trace = "a: $a, b: $b";
+ String trace;
+}
+
+class M {}
+
+class D = C<String> with M;
+
+class E extends D {}
+
+class F extends C<int> with M {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/mixin_covariant.dart.textual_outline.expect b/pkg/front_end/testcases/general/mixin_covariant.dart.textual_outline.expect
new file mode 100644
index 0000000..c16e66d
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin_covariant.dart.textual_outline.expect
@@ -0,0 +1,89 @@
+typedef void TakeInts(int a, int b, int c, int d, int e);
+typedef void TakeObjectsAndInts(Object a, int b, Object c, int d, int e);
+typedef void TakeObjects(Object a, Object b, Object c, Object d, Object e);
+typedef void TakeOptionalInts([int a, int b, int c, int d]);
+typedef void TakeOptionalObjectsAndInts([Object a, int b, Object c, int d]);
+typedef void TakeNamedInts({int a, int b, int c, int d});
+typedef void TakeNamedObjectsAndInts({Object a, int b, Object c, int d});
+
+class M1 {
+ method(covariant int a, int b) {}
+}
+
+class M2 {
+ method(int a, covariant int b) {}
+}
+
+class C extends Object with M1, M2 {}
+
+class Direct {
+ void positional(covariant int a, int b, covariant int c, int d, int e) {}
+ void optional([covariant int a, int b, covariant int c, int d]) {}
+ void named({covariant int a, int b, covariant int c, int d}) {}
+}
+
+class Inherited extends Direct {}
+
+class Override1 {
+ void method(covariant int a, int b, int c, int d, int e) {}
+}
+
+class Override2 extends Override1 {
+ void method(int a, int b, covariant int c, int d, int e) {}
+}
+
+class Override3 extends Override2 {
+ void method(int a, int b, int c, int d, int e) {}
+}
+
+abstract class Implement1 {
+ void method(covariant int a, int b, int c, int d, int e) {}
+}
+
+class Implement2 {
+ void method(int a, covariant int b, int c, int d, int e) {}
+}
+
+class Implement3 {
+ void method(int a, int b, covariant int c, int d, int e) {}
+}
+
+class Implement4 implements Implement3 {
+ void method(int a, int b, int c, covariant int d, int e) {}
+}
+
+class Implement5 implements Implement1, Implement2, Implement4 {
+ void method(int a, int b, int c, int d, covariant int e) {}
+}
+
+class Interface1 {
+ void method(covariant int a, int b, int c, int d, int e) {}
+}
+
+class Interface2 {
+ void method(int a, covariant int b, int c, int d, int e) {}
+}
+
+class Mixin1 {
+ void method(int a, int b, covariant int c, int d, int e) {}
+}
+
+class Mixin2 {
+ void method(int a, int b, int c, covariant int d, int e) {}
+}
+
+class Superclass {
+ void method(int a, int b, int c, int d, covariant int e) {}
+}
+
+class Mixed extends Superclass
+ with Mixin1, Mixin2
+ implements Interface1, Interface2 {}
+
+void main() {}
+void testDirect() {}
+void testInherited() {}
+void testOverridden() {}
+void testImplemented() {}
+void testMixed() {}
+void isTrue(bool value) {}
diff --git a/pkg/front_end/testcases/general/mixin_covariant.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/mixin_covariant.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c1e2d8c
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin_covariant.dart.textual_outline_modelled.expect
@@ -0,0 +1,88 @@
+abstract class Implement1 {
+ void method(covariant int a, int b, int c, int d, int e) {}
+}
+
+class C extends Object with M1, M2 {}
+
+class Direct {
+ void named({covariant int a, int b, covariant int c, int d}) {}
+ void optional([covariant int a, int b, covariant int c, int d]) {}
+ void positional(covariant int a, int b, covariant int c, int d, int e) {}
+}
+
+class Implement2 {
+ void method(int a, covariant int b, int c, int d, int e) {}
+}
+
+class Implement3 {
+ void method(int a, int b, covariant int c, int d, int e) {}
+}
+
+class Implement4 implements Implement3 {
+ void method(int a, int b, int c, covariant int d, int e) {}
+}
+
+class Implement5 implements Implement1, Implement2, Implement4 {
+ void method(int a, int b, int c, int d, covariant int e) {}
+}
+
+class Inherited extends Direct {}
+
+class Interface1 {
+ void method(covariant int a, int b, int c, int d, int e) {}
+}
+
+class Interface2 {
+ void method(int a, covariant int b, int c, int d, int e) {}
+}
+
+class M1 {
+ method(covariant int a, int b) {}
+}
+
+class M2 {
+ method(int a, covariant int b) {}
+}
+
+class Mixed extends Superclass
+ with Mixin1, Mixin2
+ implements Interface1, Interface2 {}
+
+class Mixin1 {
+ void method(int a, int b, covariant int c, int d, int e) {}
+}
+
+class Mixin2 {
+ void method(int a, int b, int c, covariant int d, int e) {}
+}
+
+class Override1 {
+ void method(covariant int a, int b, int c, int d, int e) {}
+}
+
+class Override2 extends Override1 {
+ void method(int a, int b, covariant int c, int d, int e) {}
+}
+
+class Override3 extends Override2 {
+ void method(int a, int b, int c, int d, int e) {}
+}
+
+class Superclass {
+ void method(int a, int b, int c, int d, covariant int e) {}
+}
+
+typedef void TakeInts(int a, int b, int c, int d, int e);
+typedef void TakeNamedInts({int a, int b, int c, int d});
+typedef void TakeNamedObjectsAndInts({Object a, int b, Object c, int d});
+typedef void TakeObjects(Object a, Object b, Object c, Object d, Object e);
+typedef void TakeObjectsAndInts(Object a, int b, Object c, int d, int e);
+typedef void TakeOptionalInts([int a, int b, int c, int d]);
+typedef void TakeOptionalObjectsAndInts([Object a, int b, Object c, int d]);
+void isTrue(bool value) {}
+void main() {}
+void testDirect() {}
+void testImplemented() {}
+void testInherited() {}
+void testMixed() {}
+void testOverridden() {}
diff --git a/pkg/front_end/testcases/general/mixin_inherited_setter_for_mixed_in_field.dart.textual_outline.expect b/pkg/front_end/testcases/general/mixin_inherited_setter_for_mixed_in_field.dart.textual_outline.expect
new file mode 100644
index 0000000..e0817ec
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin_inherited_setter_for_mixed_in_field.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+class A {}
+
+class C<T extends A> {
+ T _field;
+ foo(T x) {}
+}
+
+class D extends C<B> {}
+
+class Foo extends Object with C<B> {}
+
+class B extends A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/mixin_inherited_setter_for_mixed_in_field.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/mixin_inherited_setter_for_mixed_in_field.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5993153
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin_inherited_setter_for_mixed_in_field.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+class A {}
+
+class B extends A {}
+
+class C<T extends A> {
+ T _field;
+ foo(T x) {}
+}
+
+class D extends C<B> {}
+
+class Foo extends Object with C<B> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/mixin_interface_conflict.dart.textual_outline.expect b/pkg/front_end/testcases/general/mixin_interface_conflict.dart.textual_outline.expect
new file mode 100644
index 0000000..d373953
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin_interface_conflict.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class B {
+ int get n => 1;
+}
+
+class C {
+ double get n => 2.0;
+}
+
+mixin M on B, C {}
+main() {}
diff --git a/pkg/front_end/testcases/general/mixin_interface_conflict.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/mixin_interface_conflict.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e2a50a1
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin_interface_conflict.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+class B {
+ int get n => 1;
+}
+
+class C {
+ double get n => 2.0;
+}
+
+main() {}
+mixin M on B, C {}
diff --git a/pkg/front_end/testcases/general/mixin_super_repeated.dart.textual_outline.expect b/pkg/front_end/testcases/general/mixin_super_repeated.dart.textual_outline.expect
new file mode 100644
index 0000000..e92d32e
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin_super_repeated.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+abstract class M {
+ var m;
+}
+
+abstract class N extends M {
+ void set superM(value) {}
+ get superM => super.m;
+}
+
+class S {}
+
+class Named = S with M, N, M;
+main() {}
diff --git a/pkg/front_end/testcases/general/mixin_super_repeated.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/mixin_super_repeated.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0877c4a
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin_super_repeated.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+abstract class M {
+ var m;
+}
+
+abstract class N extends M {
+ get superM => super.m;
+ void set superM(value) {}
+}
+
+class S {}
+
+class Named = S with M, N, M;
+main() {}
diff --git a/pkg/front_end/testcases/general/mixin_with_static_member.dart.textual_outline.expect b/pkg/front_end/testcases/general/mixin_with_static_member.dart.textual_outline.expect
new file mode 100644
index 0000000..2e0fe67
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin_with_static_member.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class A extends B with M {}
+
+class B {
+ final Object m = null;
+}
+
+class M {
+ static Object m() => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/mixin_with_static_member.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/mixin_with_static_member.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2e0fe67
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin_with_static_member.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+class A extends B with M {}
+
+class B {
+ final Object m = null;
+}
+
+class M {
+ static Object m() => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/named_function_scope.dart.textual_outline.expect b/pkg/front_end/testcases/general/named_function_scope.dart.textual_outline.expect
new file mode 100644
index 0000000..b05a61b
--- /dev/null
+++ b/pkg/front_end/testcases/general/named_function_scope.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class T {}
+
+class V {}
+
+test() {}
+void main() {}
diff --git a/pkg/front_end/testcases/general/named_function_scope.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/named_function_scope.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b05a61b
--- /dev/null
+++ b/pkg/front_end/testcases/general/named_function_scope.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class T {}
+
+class V {}
+
+test() {}
+void main() {}
diff --git a/pkg/front_end/testcases/general/named_parameters.dart.textual_outline.expect b/pkg/front_end/testcases/general/named_parameters.dart.textual_outline.expect
new file mode 100644
index 0000000..cf9319d
--- /dev/null
+++ b/pkg/front_end/testcases/general/named_parameters.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+class Superclass {
+ foo({alpha, beta}) {}
+ bar({beta, alpha}) {}
+ namedCallback(callback({String alpha, int beta})) {}
+}
+
+class Subclass extends Superclass {
+ foo({beta, alpha}) {}
+ bar({alpha, beta}) {}
+ namedCallback(callback({int beta, String alpha})) {}
+}
+
+topLevelNamed(beta, alpha, {gamma, delta}) {}
+topLevelOptional(beta, alpha, [gamma, delta]) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/named_parameters.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/named_parameters.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1a020dc2
--- /dev/null
+++ b/pkg/front_end/testcases/general/named_parameters.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+class Subclass extends Superclass {
+ bar({alpha, beta}) {}
+ foo({beta, alpha}) {}
+ namedCallback(callback({int beta, String alpha})) {}
+}
+
+class Superclass {
+ bar({beta, alpha}) {}
+ foo({alpha, beta}) {}
+ namedCallback(callback({String alpha, int beta})) {}
+}
+
+main() {}
+topLevelNamed(beta, alpha, {gamma, delta}) {}
+topLevelOptional(beta, alpha, [gamma, delta]) {}
diff --git a/pkg/front_end/testcases/general/native_as_name.dart.textual_outline.expect b/pkg/front_end/testcases/general/native_as_name.dart.textual_outline.expect
new file mode 100644
index 0000000..546fe36
--- /dev/null
+++ b/pkg/front_end/testcases/general/native_as_name.dart.textual_outline.expect
@@ -0,0 +1,24 @@
+main() {}
+
+class W {
+ String native;
+ W() : native = "field";
+}
+
+class X {
+ String native() => "method";
+}
+
+abstract class Y1 {
+ String get native;
+}
+
+class Y2 extends Y1 {
+ @override
+ String get native => "getter";
+}
+
+class Z {
+ set native(String s) => f = s;
+ String f;
+}
diff --git a/pkg/front_end/testcases/general/native_as_name.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/native_as_name.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2897b36
--- /dev/null
+++ b/pkg/front_end/testcases/general/native_as_name.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+abstract class Y1 {
+ String get native;
+}
+
+class W {
+ String native;
+ W() : native = "field";
+}
+
+class X {
+ String native() => "method";
+}
+
+class Y2 extends Y1 {
+ @override
+ String get native => "getter";
+}
+
+class Z {
+ String f;
+ set native(String s) => f = s;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/nested_implicit_const_with_env_var.dart.textual_outline.expect b/pkg/front_end/testcases/general/nested_implicit_const_with_env_var.dart.textual_outline.expect
new file mode 100644
index 0000000..0bad45d
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_implicit_const_with_env_var.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+const int foo = const int.fromEnvironment("fisk");
+
+class A {
+ final int bar;
+ const A(this.bar);
+}
+
+class B {
+ final A baz;
+ const B(this.baz);
+}
+
+class C {
+ fun() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/nested_implicit_const_with_env_var.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/nested_implicit_const_with_env_var.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c2ae67e
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_implicit_const_with_env_var.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+class A {
+ const A(this.bar);
+ final int bar;
+}
+
+class B {
+ const B(this.baz);
+ final A baz;
+}
+
+class C {
+ fun() {}
+}
+
+const int foo = const int.fromEnvironment("fisk");
+main() {}
diff --git a/pkg/front_end/testcases/general/nested_property_set.dart.textual_outline.expect b/pkg/front_end/testcases/general/nested_property_set.dart.textual_outline.expect
new file mode 100644
index 0000000..bf9e0fc
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_property_set.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+class NumField {
+ num field;
+}
+
+class IntField {
+ int field;
+}
+
+class DoubleField {
+ double field;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/nested_property_set.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/nested_property_set.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..15987b1
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_property_set.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+class DoubleField {
+ double field;
+}
+
+class IntField {
+ int field;
+}
+
+class NumField {
+ num field;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/nested_variable_set.dart.textual_outline.expect b/pkg/front_end/testcases/general/nested_variable_set.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_variable_set.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/nested_variable_set.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/nested_variable_set.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_variable_set.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/nested_variance.dart.textual_outline.expect b/pkg/front_end/testcases/general/nested_variance.dart.textual_outline.expect
new file mode 100644
index 0000000..5ce634d
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_variance.dart.textual_outline.expect
@@ -0,0 +1,52 @@
+typedef F<X> = void Function<Y extends X>();
+F<X> toF<X>(X x) => null;
+typedef Fcov<X> = X Function();
+typedef Fcon<X> = Function(X);
+typedef Finv<X> = X Function(X);
+
+class Acov<X extends Fcov<Y>, Y> {}
+
+class Acon<X extends Fcon<Y>, Y> {}
+
+class Ainv<X extends Finv<Y>, Y> {}
+
+typedef FcovBound<X extends num> = X Function();
+typedef FconBound<X extends num> = Function(X);
+typedef FinvBound<X extends num> = X Function(X);
+
+class AcovBound<X extends FcovBound<Y>, Y extends num> {}
+
+class AconBound<X extends FconBound<Y>, Y extends num> {}
+
+class AinvBound<X extends FinvBound<Y>, Y extends num> {}
+
+class A<X> {}
+
+typedef FcovCyclicBound<X extends A<X>> = X Function();
+typedef FconCyclicBound<X extends A<X>> = Function(X);
+typedef FinvCyclicBound<X extends A<X>> = X Function(X);
+
+class AcovCyclicBound<X extends FcovCyclicBound<Y>, Y extends A<Y>> {}
+
+class AconCyclicBound<X extends FconCyclicBound<Y>, Y extends A<Y>> {}
+
+class AinvCyclicBound<X extends FinvCyclicBound<Y>, Y extends A<Y>> {}
+
+typedef FcovCyclicCoBound<X extends Function(X)> = X Function();
+typedef FconCyclicCoBound<X extends Function(X)> = Function(X);
+typedef FinvCyclicCoBound<X extends Function(X)> = X Function(X);
+
+class AcovCyclicCoBound<X extends FcovCyclicCoBound<Y>, Y extends Function(Y)> {
+}
+
+class AconCyclicCoBound<X extends FconCyclicCoBound<Y>, Y extends Function(Y)> {
+}
+
+class AinvCyclicCoBound<X extends FinvCyclicCoBound<Y>, Y extends Function(Y)> {
+}
+
+class B<X> {}
+
+void testTypeAliasAsTypeArgument() {}
+void testNested() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/nested_variance.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/nested_variance.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6d86b71
--- /dev/null
+++ b/pkg/front_end/testcases/general/nested_variance.dart.textual_outline_modelled.expect
@@ -0,0 +1,49 @@
+F<X> toF<X>(X x) => null;
+
+class A<X> {}
+
+class Acon<X extends Fcon<Y>, Y> {}
+
+class AconBound<X extends FconBound<Y>, Y extends num> {}
+
+class AconCyclicBound<X extends FconCyclicBound<Y>, Y extends A<Y>> {}
+
+class AconCyclicCoBound<X extends FconCyclicCoBound<Y>, Y extends Function(Y)> {
+}
+
+class Acov<X extends Fcov<Y>, Y> {}
+
+class AcovBound<X extends FcovBound<Y>, Y extends num> {}
+
+class AcovCyclicBound<X extends FcovCyclicBound<Y>, Y extends A<Y>> {}
+
+class AcovCyclicCoBound<X extends FcovCyclicCoBound<Y>, Y extends Function(Y)> {
+}
+
+class Ainv<X extends Finv<Y>, Y> {}
+
+class AinvBound<X extends FinvBound<Y>, Y extends num> {}
+
+class AinvCyclicBound<X extends FinvCyclicBound<Y>, Y extends A<Y>> {}
+
+class AinvCyclicCoBound<X extends FinvCyclicCoBound<Y>, Y extends Function(Y)> {
+}
+
+class B<X> {}
+
+main() {}
+typedef F<X> = void Function<Y extends X>();
+typedef Fcon<X> = Function(X);
+typedef FconBound<X extends num> = Function(X);
+typedef FconCyclicBound<X extends A<X>> = Function(X);
+typedef FconCyclicCoBound<X extends Function(X)> = Function(X);
+typedef Fcov<X> = X Function();
+typedef FcovBound<X extends num> = X Function();
+typedef FcovCyclicBound<X extends A<X>> = X Function();
+typedef FcovCyclicCoBound<X extends Function(X)> = X Function();
+typedef Finv<X> = X Function(X);
+typedef FinvBound<X extends num> = X Function(X);
+typedef FinvCyclicBound<X extends A<X>> = X Function(X);
+typedef FinvCyclicCoBound<X extends Function(X)> = X Function(X);
+void testNested() {}
+void testTypeAliasAsTypeArgument() {}
diff --git a/pkg/front_end/testcases/general/no_such_method_private_setter.dart.textual_outline.expect b/pkg/front_end/testcases/general/no_such_method_private_setter.dart.textual_outline.expect
new file mode 100644
index 0000000..8aa3b3b
--- /dev/null
+++ b/pkg/front_end/testcases/general/no_such_method_private_setter.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import './no_such_method_private_setter_lib.dart';
+
+class Foo implements Bar {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/no_such_method_private_setter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/no_such_method_private_setter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8aa3b3b
--- /dev/null
+++ b/pkg/front_end/testcases/general/no_such_method_private_setter.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import './no_such_method_private_setter_lib.dart';
+
+class Foo implements Bar {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/non_covariant_checks.dart.textual_outline.expect b/pkg/front_end/testcases/general/non_covariant_checks.dart.textual_outline.expect
new file mode 100644
index 0000000..d3da106
--- /dev/null
+++ b/pkg/front_end/testcases/general/non_covariant_checks.dart.textual_outline.expect
@@ -0,0 +1,79 @@
+class C<T> {
+ C(this.field1)
+ : field2 = (() => field1),
+ field3 = ((T t) {}),
+ field4 = ((T t) => t),
+ field5 = (() => () => field1),
+ field6 = ((T Function() f) {}),
+ field7 = ((T Function() f) => field1),
+ field8 = ((void Function(T) f) {}),
+ field9 = ((void Function(T) f) => field1),
+ field10 = ((T Function(T) f) {}),
+ field11 = ((T Function(T) f) => field1),
+ field12 = <S extends T>() => null,
+ field13 = <S extends T>(S s) {},
+ field14 = <S extends T>(S s) => s,
+ field15 = ((S Function<S extends T>() f) {});
+ T field1;
+ T Function() field2;
+ void Function(T) field3;
+ T Function(T) field4;
+ T Function() Function() field5;
+ void Function(T Function()) field6;
+ T Function(T Function()) field7;
+ void Function(void Function(T)) field8;
+ T Function(void Function(T)) field9;
+ void Function(T Function(T)) field10;
+ T Function(T Function(T)) field11;
+ S Function<S extends T>() field12;
+ void Function<S extends T>(S) field13;
+ S Function<S extends T>(S) field14;
+ void Function(S Function<S extends T>()) field15;
+ T get getter1 => field1;
+ T Function() get getter2 => field2;
+ void Function(T) get getter3 => field3;
+ T Function(T) get getter4 => field4;
+ T Function() Function() get getter5 => field5;
+ void Function(T Function()) get getter6 => field6;
+ T Function(T Function()) get getter7 => field7;
+ void Function(void Function(T)) get getter8 => field8;
+ T Function(void Function(T)) get getter9 => field9;
+ void Function(T Function(T)) get getter10 => field10;
+ T Function(T Function(T)) get getter11 => field11;
+ S Function<S extends T>() get getter12 => field12;
+ void Function<S extends T>(S) get getter13 => field13;
+ S Function<S extends T>(S) get getter14 => field14;
+ void Function(S Function<S extends T>()) get getter15 => field15;
+ void set setter1(T value) {}
+ void set setter2(T Function() value) {}
+ void set setter3(void Function(T) value) {}
+ void set setter4(T Function(T) value) {}
+ void set setter5(T Function() Function() value) {}
+ void set setter6(void Function(T Function()) value) {}
+ void set setter7(T Function(T Function()) value) {}
+ void set setter8(void Function(void Function(T)) value) {}
+ void set setter9(T Function(void Function(T)) value) {}
+ void set setter10(void Function(T Function(T)) value) {}
+ void set setter11(T Function(T Function(T)) value) {}
+ void set setter12(S Function<S extends T>() value) {}
+ void set setter13(void Function<S extends T>(S) value) {}
+ void set setter14(S Function<S extends T>(S) value) {}
+ void set setter15(void Function(S Function<S extends T>()) value) {}
+ void method1(T value) {}
+ void method2(T Function() value) {}
+ void method3(void Function(T) value) {}
+ void method4(T Function(T) value) {}
+ void method5(T Function() Function() value) {}
+ void method6(void Function(T Function()) value) {}
+ void method7(T Function(T Function()) value) {}
+ void method8(void Function(void Function(T)) value) {}
+ void method9(T Function(void Function(T)) value) {}
+ void method10(void Function(T Function(T)) value) {}
+ void method11(T Function(T Function(T)) value) {}
+ void method12(S Function<S extends T>() value) {}
+ void method13(void Function<S extends T>(S) value) {}
+ void method14(S Function<S extends T>(S) value) {}
+ void method15(void Function(S Function<S extends T>()) value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/non_covariant_checks.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/non_covariant_checks.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fc7f6db
--- /dev/null
+++ b/pkg/front_end/testcases/general/non_covariant_checks.dart.textual_outline_modelled.expect
@@ -0,0 +1,79 @@
+class C<T> {
+ C(this.field1)
+ : field2 = (() => field1),
+ field3 = ((T t) {}),
+ field4 = ((T t) => t),
+ field5 = (() => () => field1),
+ field6 = ((T Function() f) {}),
+ field7 = ((T Function() f) => field1),
+ field8 = ((void Function(T) f) {}),
+ field9 = ((void Function(T) f) => field1),
+ field10 = ((T Function(T) f) {}),
+ field11 = ((T Function(T) f) => field1),
+ field12 = <S extends T>() => null,
+ field13 = <S extends T>(S s) {},
+ field14 = <S extends T>(S s) => s,
+ field15 = ((S Function<S extends T>() f) {});
+ S Function<S extends T>() field12;
+ S Function<S extends T>() get getter12 => field12;
+ S Function<S extends T>(S) field14;
+ S Function<S extends T>(S) get getter14 => field14;
+ T Function(T Function()) field7;
+ T Function(T Function()) get getter7 => field7;
+ T Function(T Function(T)) field11;
+ T Function(T Function(T)) get getter11 => field11;
+ T Function(T) field4;
+ T Function(T) get getter4 => field4;
+ T Function() Function() field5;
+ T Function() Function() get getter5 => field5;
+ T Function() field2;
+ T Function() get getter2 => field2;
+ T Function(void Function(T)) field9;
+ T Function(void Function(T)) get getter9 => field9;
+ T field1;
+ T get getter1 => field1;
+ void Function(T Function()) field6;
+ void Function(T Function()) get getter6 => field6;
+ void Function(T Function(T)) field10;
+ void Function(T Function(T)) get getter10 => field10;
+ void Function(T) field3;
+ void Function(T) get getter3 => field3;
+ void Function(S Function<S extends T>()) field15;
+ void Function(S Function<S extends T>()) get getter15 => field15;
+ void Function(void Function(T)) field8;
+ void Function(void Function(T)) get getter8 => field8;
+ void Function<S extends T>(S) field13;
+ void Function<S extends T>(S) get getter13 => field13;
+ void method1(T value) {}
+ void method10(void Function(T Function(T)) value) {}
+ void method11(T Function(T Function(T)) value) {}
+ void method12(S Function<S extends T>() value) {}
+ void method13(void Function<S extends T>(S) value) {}
+ void method14(S Function<S extends T>(S) value) {}
+ void method15(void Function(S Function<S extends T>()) value) {}
+ void method2(T Function() value) {}
+ void method3(void Function(T) value) {}
+ void method4(T Function(T) value) {}
+ void method5(T Function() Function() value) {}
+ void method6(void Function(T Function()) value) {}
+ void method7(T Function(T Function()) value) {}
+ void method8(void Function(void Function(T)) value) {}
+ void method9(T Function(void Function(T)) value) {}
+ void set setter1(T value) {}
+ void set setter10(void Function(T Function(T)) value) {}
+ void set setter11(T Function(T Function(T)) value) {}
+ void set setter12(S Function<S extends T>() value) {}
+ void set setter13(void Function<S extends T>(S) value) {}
+ void set setter14(S Function<S extends T>(S) value) {}
+ void set setter15(void Function(S Function<S extends T>()) value) {}
+ void set setter2(T Function() value) {}
+ void set setter3(void Function(T) value) {}
+ void set setter4(T Function(T) value) {}
+ void set setter5(T Function() Function() value) {}
+ void set setter6(void Function(T Function()) value) {}
+ void set setter7(T Function(T Function()) value) {}
+ void set setter8(void Function(void Function(T)) value) {}
+ void set setter9(T Function(void Function(T)) value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/null_aware.dart.textual_outline.expect b/pkg/front_end/testcases/general/null_aware.dart.textual_outline.expect
new file mode 100644
index 0000000..987eca0
--- /dev/null
+++ b/pkg/front_end/testcases/general/null_aware.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class Foo {
+ int field;
+ static int staticField;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/null_aware.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/null_aware.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..987eca0
--- /dev/null
+++ b/pkg/front_end/testcases/general/null_aware.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class Foo {
+ int field;
+ static int staticField;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/null_aware_for_in.dart.textual_outline.expect b/pkg/front_end/testcases/general/null_aware_for_in.dart.textual_outline.expect
new file mode 100644
index 0000000..52b290c
--- /dev/null
+++ b/pkg/front_end/testcases/general/null_aware_for_in.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+class Class {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/null_aware_for_in.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/null_aware_for_in.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..52b290c
--- /dev/null
+++ b/pkg/front_end/testcases/general/null_aware_for_in.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+class Class {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/null_aware_postfix.dart.textual_outline.expect b/pkg/front_end/testcases/general/null_aware_postfix.dart.textual_outline.expect
new file mode 100644
index 0000000..5602235
--- /dev/null
+++ b/pkg/front_end/testcases/general/null_aware_postfix.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class A {
+ B b;
+}
+
+class B {
+ C operator +(int i) => null;
+}
+
+class C extends B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/null_aware_postfix.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/null_aware_postfix.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5602235
--- /dev/null
+++ b/pkg/front_end/testcases/general/null_aware_postfix.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+class A {
+ B b;
+}
+
+class B {
+ C operator +(int i) => null;
+}
+
+class C extends B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/null_aware_spread.dart.textual_outline.expect b/pkg/front_end/testcases/general/null_aware_spread.dart.textual_outline.expect
new file mode 100644
index 0000000..321264d
--- /dev/null
+++ b/pkg/front_end/testcases/general/null_aware_spread.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+nullAwareListSpread(List<String> list) {}
+nullAwareSetSpread(Set<String> set) {}
+nullAwareMapSpread(Map<int, String> map) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/null_aware_spread.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/null_aware_spread.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6c84dac
--- /dev/null
+++ b/pkg/front_end/testcases/general/null_aware_spread.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+main() {}
+nullAwareListSpread(List<String> list) {}
+nullAwareMapSpread(Map<int, String> map) {}
+nullAwareSetSpread(Set<String> set) {}
diff --git a/pkg/front_end/testcases/general/operator_method_not_found.dart.textual_outline.expect b/pkg/front_end/testcases/general/operator_method_not_found.dart.textual_outline.expect
new file mode 100644
index 0000000..a467bf8
--- /dev/null
+++ b/pkg/front_end/testcases/general/operator_method_not_found.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+class Foo {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/operator_method_not_found.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/operator_method_not_found.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a467bf8
--- /dev/null
+++ b/pkg/front_end/testcases/general/operator_method_not_found.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+class Foo {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/operators.dart.textual_outline.expect b/pkg/front_end/testcases/general/operators.dart.textual_outline.expect
new file mode 100644
index 0000000..21c00c7
--- /dev/null
+++ b/pkg/front_end/testcases/general/operators.dart.textual_outline.expect
@@ -0,0 +1,24 @@
+class Operators {
+ operator +(other) => null;
+ operator &(other) => null;
+ operator ~() => null;
+ operator |(other) => null;
+ operator ^(other) => null;
+ operator /(other) => null;
+ operator ==(other) => null;
+ operator >(other) => null;
+ operator >=(other) => null;
+ operator [](index) => null;
+ void operator []=(index, value) {}
+ operator <<(other) => null;
+ operator <(other) => null;
+ operator <=(other) => null;
+ operator *(other) => null;
+ operator %(other) => null;
+ operator >>(other) => null;
+ operator -(other) => null;
+ operator ~/(other) => null;
+ operator -() => null;
+}
+
+main(arguments) {}
diff --git a/pkg/front_end/testcases/general/operators.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/operators.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c6b5f5a
--- /dev/null
+++ b/pkg/front_end/testcases/general/operators.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+class Operators {
+ operator %(other) => null;
+ operator &(other) => null;
+ operator *(other) => null;
+ operator +(other) => null;
+ operator -() => null;
+ operator -(other) => null;
+ operator /(other) => null;
+ operator <(other) => null;
+ operator <<(other) => null;
+ operator <=(other) => null;
+ operator ==(other) => null;
+ operator >(other) => null;
+ operator >=(other) => null;
+ operator >>(other) => null;
+ operator [](index) => null;
+ operator ^(other) => null;
+ operator |(other) => null;
+ operator ~() => null;
+ operator ~/(other) => null;
+ void operator []=(index, value) {}
+}
+
+main(arguments) {}
diff --git a/pkg/front_end/testcases/general/optional.dart.textual_outline.expect b/pkg/front_end/testcases/general/optional.dart.textual_outline.expect
new file mode 100644
index 0000000..737d5bc
--- /dev/null
+++ b/pkg/front_end/testcases/general/optional.dart.textual_outline.expect
@@ -0,0 +1,28 @@
+class Foo {
+ method(x, [y, z]) {}
+}
+
+abstract class External {
+ String externalMethod(int x, [int y, int z]);
+ void listen(Listener listener);
+}
+
+external External createExternal();
+
+abstract class Listener {
+ void event(String input, [int x, int y]);
+}
+
+class TestListener extends Listener {
+ void event(input, [x, y]) {}
+}
+
+class ExtendedListener extends Listener {
+ void event(input, [x, y, z]) {}
+}
+
+class InvalidListener {
+ void event(input, [x]) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/optional.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/optional.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..53593a5
--- /dev/null
+++ b/pkg/front_end/testcases/general/optional.dart.textual_outline_modelled.expect
@@ -0,0 +1,27 @@
+abstract class External {
+ String externalMethod(int x, [int y, int z]);
+ void listen(Listener listener);
+}
+
+abstract class Listener {
+ void event(String input, [int x, int y]);
+}
+
+class ExtendedListener extends Listener {
+ void event(input, [x, y, z]) {}
+}
+
+class Foo {
+ method(x, [y, z]) {}
+}
+
+class InvalidListener {
+ void event(input, [x]) {}
+}
+
+class TestListener extends Listener {
+ void event(input, [x, y]) {}
+}
+
+external External createExternal();
+main() {}
diff --git a/pkg/front_end/testcases/general/override.dart.textual_outline.expect b/pkg/front_end/testcases/general/override.dart.textual_outline.expect
new file mode 100644
index 0000000..272b930
--- /dev/null
+++ b/pkg/front_end/testcases/general/override.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+class Foo {}
+
+class Bar extends Foo {}
+
+class Base {
+ Foo method() {}
+}
+
+class Sub extends Base {
+ Foo method() {}
+}
+
+main(List<String> args) {}
diff --git a/pkg/front_end/testcases/general/override.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/override.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ef2c070
--- /dev/null
+++ b/pkg/front_end/testcases/general/override.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+class Bar extends Foo {}
+
+class Base {
+ Foo method() {}
+}
+
+class Foo {}
+
+class Sub extends Base {
+ Foo method() {}
+}
+
+main(List<String> args) {}
diff --git a/pkg/front_end/testcases/general/override_check_accessor_after_inference.dart.textual_outline.expect b/pkg/front_end/testcases/general/override_check_accessor_after_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..8e908b9
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_check_accessor_after_inference.dart.textual_outline.expect
@@ -0,0 +1,25 @@
+class A {}
+
+class B extends A {}
+
+class C {
+ void set x(A value) {}
+ B get y => null;
+}
+
+class D extends C {
+ void set x(value) {}
+ get y => null;
+}
+
+class E extends D {
+ void set x(A value) {}
+ B get y => null;
+}
+
+class F extends D {
+ void set x(B value) {}
+ A get y => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/override_check_accessor_after_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/override_check_accessor_after_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..768ee0f
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_check_accessor_after_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,25 @@
+class A {}
+
+class B extends A {}
+
+class C {
+ B get y => null;
+ void set x(A value) {}
+}
+
+class D extends C {
+ get y => null;
+ void set x(value) {}
+}
+
+class E extends D {
+ B get y => null;
+ void set x(A value) {}
+}
+
+class F extends D {
+ A get y => null;
+ void set x(B value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/override_check_accessor_basic.dart.textual_outline.expect b/pkg/front_end/testcases/general/override_check_accessor_basic.dart.textual_outline.expect
new file mode 100644
index 0000000..9a762a7
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_check_accessor_basic.dart.textual_outline.expect
@@ -0,0 +1,20 @@
+class A {}
+
+class B extends A {}
+
+class C {
+ void set x(A value) {}
+ A get y => null;
+}
+
+class D extends C {
+ void set x(Object value) {}
+ B get y => null;
+}
+
+class E extends C {
+ void set x(B value) {}
+ Object get y => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/override_check_accessor_basic.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/override_check_accessor_basic.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..363c517
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_check_accessor_basic.dart.textual_outline_modelled.expect
@@ -0,0 +1,20 @@
+class A {}
+
+class B extends A {}
+
+class C {
+ A get y => null;
+ void set x(A value) {}
+}
+
+class D extends C {
+ B get y => null;
+ void set x(Object value) {}
+}
+
+class E extends C {
+ Object get y => null;
+ void set x(B value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/override_check_accessor_with_covariant_modifier.dart.textual_outline.expect b/pkg/front_end/testcases/general/override_check_accessor_with_covariant_modifier.dart.textual_outline.expect
new file mode 100644
index 0000000..015eb02
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_check_accessor_with_covariant_modifier.dart.textual_outline.expect
@@ -0,0 +1,23 @@
+class A {}
+
+class B extends A {}
+
+class C {
+ void set x1(covariant A value) {}
+ void set x2(A value) {}
+ void set x3(covariant A value) {}
+ void set x4(A value) {}
+ void set x5(covariant A value) {}
+ void set x6(covariant B value) {}
+}
+
+class D extends C {
+ void set x1(B value) {}
+ void set x2(covariant B value) {}
+ void set x3(covariant B value) {}
+ void set x4(B value) {}
+ void set x5(covariant String value) {}
+ void set x6(covariant A value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/override_check_accessor_with_covariant_modifier.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/override_check_accessor_with_covariant_modifier.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..015eb02
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_check_accessor_with_covariant_modifier.dart.textual_outline_modelled.expect
@@ -0,0 +1,23 @@
+class A {}
+
+class B extends A {}
+
+class C {
+ void set x1(covariant A value) {}
+ void set x2(A value) {}
+ void set x3(covariant A value) {}
+ void set x4(A value) {}
+ void set x5(covariant A value) {}
+ void set x6(covariant B value) {}
+}
+
+class D extends C {
+ void set x1(B value) {}
+ void set x2(covariant B value) {}
+ void set x3(covariant B value) {}
+ void set x4(B value) {}
+ void set x5(covariant String value) {}
+ void set x6(covariant A value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/override_check_after_inference.dart.textual_outline.expect b/pkg/front_end/testcases/general/override_check_after_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..b2c8457
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_check_after_inference.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+class A {}
+
+class B extends A {}
+
+class C {
+ void f(A x) {}
+}
+
+class D extends C {
+ void f(x) {}
+}
+
+class E extends D {
+ void f(A x) {}
+}
+
+class F extends D {
+ void f(B x) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/override_check_after_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/override_check_after_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b2c8457
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_check_after_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+class A {}
+
+class B extends A {}
+
+class C {
+ void f(A x) {}
+}
+
+class D extends C {
+ void f(x) {}
+}
+
+class E extends D {
+ void f(A x) {}
+}
+
+class F extends D {
+ void f(B x) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/override_check_basic.dart.textual_outline.expect b/pkg/front_end/testcases/general/override_check_basic.dart.textual_outline.expect
new file mode 100644
index 0000000..d6322d8
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_check_basic.dart.textual_outline.expect
@@ -0,0 +1,26 @@
+class A {}
+
+class B extends A {}
+
+class C {
+ void f1(A x) {}
+ void f2([A x]) {}
+ void f3({A x}) {}
+ A f4() {}
+}
+
+class D extends C {
+ void f1(Object x) {}
+ void f2([Object x]) {}
+ void f3({Object x}) {}
+ B f4() {}
+}
+
+class E extends C {
+ void f1(B x) {}
+ void f2([B x]) {}
+ void f3({B x}) {}
+ Object f4() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/override_check_basic.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/override_check_basic.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7ca06d3
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_check_basic.dart.textual_outline_modelled.expect
@@ -0,0 +1,26 @@
+class A {}
+
+class B extends A {}
+
+class C {
+ A f4() {}
+ void f1(A x) {}
+ void f2([A x]) {}
+ void f3({A x}) {}
+}
+
+class D extends C {
+ B f4() {}
+ void f1(Object x) {}
+ void f2([Object x]) {}
+ void f3({Object x}) {}
+}
+
+class E extends C {
+ Object f4() {}
+ void f1(B x) {}
+ void f2([B x]) {}
+ void f3({B x}) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/override_check_generic_method_f_bounded.dart.textual_outline.expect b/pkg/front_end/testcases/general/override_check_generic_method_f_bounded.dart.textual_outline.expect
new file mode 100644
index 0000000..eaac90c
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_check_generic_method_f_bounded.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+class Foo<T extends Foo<T>> {}
+
+abstract class Bar {
+ void fisk<S extends Foo<S>>();
+}
+
+class Hest implements Bar {
+ @override
+ void fisk<U extends Foo<U>>() {}
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/override_check_generic_method_f_bounded.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/override_check_generic_method_f_bounded.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cdebc76
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_check_generic_method_f_bounded.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+abstract class Bar {
+ void fisk<S extends Foo<S>>();
+}
+
+class Foo<T extends Foo<T>> {}
+
+class Hest implements Bar {
+ @override
+ void fisk<U extends Foo<U>>() {}
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/override_check_two_substitutions.dart.textual_outline.expect b/pkg/front_end/testcases/general/override_check_two_substitutions.dart.textual_outline.expect
new file mode 100644
index 0000000..9548980
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_check_two_substitutions.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class A<T> {
+ void f<U>(Map<T, U> m) {}
+}
+
+class B extends A<String> {
+ void f<V>(Map<String, V> m) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/override_check_two_substitutions.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/override_check_two_substitutions.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9548980
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_check_two_substitutions.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class A<T> {
+ void f<U>(Map<T, U> m) {}
+}
+
+class B extends A<String> {
+ void f<V>(Map<String, V> m) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/override_check_with_covariant_modifier.dart.textual_outline.expect b/pkg/front_end/testcases/general/override_check_with_covariant_modifier.dart.textual_outline.expect
new file mode 100644
index 0000000..1c8bfe2
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_check_with_covariant_modifier.dart.textual_outline.expect
@@ -0,0 +1,23 @@
+class A {}
+
+class B extends A {}
+
+class C {
+ void f1(covariant A x) {}
+ void f2(A x) {}
+ void f3(covariant A x) {}
+ void f4(A x) {}
+ void f5(covariant A x) {}
+ void f6(covariant B x) {}
+}
+
+class D extends C {
+ void f1(B x) {}
+ void f2(covariant B x) {}
+ void f3(covariant B x) {}
+ void f4(B x) {}
+ void f5(covariant String x) {}
+ void f6(covariant A x) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/override_check_with_covariant_modifier.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/override_check_with_covariant_modifier.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1c8bfe2
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_check_with_covariant_modifier.dart.textual_outline_modelled.expect
@@ -0,0 +1,23 @@
+class A {}
+
+class B extends A {}
+
+class C {
+ void f1(covariant A x) {}
+ void f2(A x) {}
+ void f3(covariant A x) {}
+ void f4(A x) {}
+ void f5(covariant A x) {}
+ void f6(covariant B x) {}
+}
+
+class D extends C {
+ void f1(B x) {}
+ void f2(covariant B x) {}
+ void f3(covariant B x) {}
+ void f4(B x) {}
+ void f5(covariant String x) {}
+ void f6(covariant A x) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/override_inference_for_getters_and_setters.dart.textual_outline.expect b/pkg/front_end/testcases/general/override_inference_for_getters_and_setters.dart.textual_outline.expect
new file mode 100644
index 0000000..d720f29
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_inference_for_getters_and_setters.dart.textual_outline.expect
@@ -0,0 +1,57 @@
+abstract class A {
+ num get getterFromGetter;
+ set setterFromSetter(num value);
+ set getterFromSetter(num value);
+ num get setterFromGetter;
+ num get getterFromGetterWithSetterConflict;
+ set getterFromGetterWithSetterConflict(num);
+ num get setterFromSetterWithGetterConflict;
+ set setterFromSetterWithGetterConflict(num);
+}
+
+abstract class B {
+ int get getterFromGetter;
+ set setterFromSetter(int value);
+ int get setterFromGetter;
+ int get setterFromSetterWithGetterConflict;
+ set getterFromGetterWithSetterConflict(int value);
+ set getterFromSetter(int value);
+}
+
+abstract class C extends A {
+ get getterFromGetter;
+ set setterFromSetter(value);
+ get getterFromSetter;
+ set setterFromGetter(value);
+ get getterFromGetterWithSetterConflict;
+ set setterFromSetterWithGetterConflict(value);
+}
+
+abstract class D extends A implements B {
+ get getterFromGetter;
+ set setterFromSetter(value);
+ get getterFromSetter;
+ set setterFromGetter(value);
+ get getterFromGetterWithSetterConflict;
+ set setterFromSetterWithGetterConflict(value);
+}
+
+abstract class E implements A {
+ get getterFromGetter;
+ set setterFromSetter(value);
+ get getterFromSetter;
+ set setterFromGetter(value);
+ get getterFromGetterWithSetterConflict;
+ set setterFromSetterWithGetterConflict(value);
+}
+
+abstract class F implements A, B {
+ get getterFromGetter;
+ set setterFromSetter(value);
+ get getterFromSetter;
+ set setterFromGetter(value);
+ get getterFromGetterWithSetterConflict;
+ set setterFromSetterWithGetterConflict(value);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/override_inference_for_getters_and_setters.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/override_inference_for_getters_and_setters.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..81cac22
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_inference_for_getters_and_setters.dart.textual_outline_modelled.expect
@@ -0,0 +1,57 @@
+abstract class A {
+ num get getterFromGetter;
+ num get getterFromGetterWithSetterConflict;
+ num get setterFromGetter;
+ num get setterFromSetterWithGetterConflict;
+ set getterFromGetterWithSetterConflict(num);
+ set getterFromSetter(num value);
+ set setterFromSetter(num value);
+ set setterFromSetterWithGetterConflict(num);
+}
+
+abstract class B {
+ int get getterFromGetter;
+ int get setterFromGetter;
+ int get setterFromSetterWithGetterConflict;
+ set getterFromGetterWithSetterConflict(int value);
+ set getterFromSetter(int value);
+ set setterFromSetter(int value);
+}
+
+abstract class C extends A {
+ get getterFromGetter;
+ get getterFromGetterWithSetterConflict;
+ get getterFromSetter;
+ set setterFromGetter(value);
+ set setterFromSetter(value);
+ set setterFromSetterWithGetterConflict(value);
+}
+
+abstract class D extends A implements B {
+ get getterFromGetter;
+ get getterFromGetterWithSetterConflict;
+ get getterFromSetter;
+ set setterFromGetter(value);
+ set setterFromSetter(value);
+ set setterFromSetterWithGetterConflict(value);
+}
+
+abstract class E implements A {
+ get getterFromGetter;
+ get getterFromGetterWithSetterConflict;
+ get getterFromSetter;
+ set setterFromGetter(value);
+ set setterFromSetter(value);
+ set setterFromSetterWithGetterConflict(value);
+}
+
+abstract class F implements A, B {
+ get getterFromGetter;
+ get getterFromGetterWithSetterConflict;
+ get getterFromSetter;
+ set setterFromGetter(value);
+ set setterFromSetter(value);
+ set setterFromSetterWithGetterConflict(value);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/override_inference_for_setters.dart.textual_outline.expect b/pkg/front_end/testcases/general/override_inference_for_setters.dart.textual_outline.expect
new file mode 100644
index 0000000..0ae1e3d
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_inference_for_setters.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class B {
+ num get foo => null;
+ set foo(dynamic newFoo) {}
+}
+
+class A extends B {
+ set foo(newFoo) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/override_inference_for_setters.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/override_inference_for_setters.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e1e629f
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_inference_for_setters.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+class A extends B {
+ set foo(newFoo) {}
+}
+
+class B {
+ num get foo => null;
+ set foo(dynamic newFoo) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/override_inference_named_parameters_ordering.dart.textual_outline.expect b/pkg/front_end/testcases/general/override_inference_named_parameters_ordering.dart.textual_outline.expect
new file mode 100644
index 0000000..231f88e
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_inference_named_parameters_ordering.dart.textual_outline.expect
@@ -0,0 +1,25 @@
+class A {
+ foo({bool c = true, bool a}) {}
+}
+
+class B extends A {
+ foo({c = true, bool a}) {}
+}
+
+class C extends B {
+ foo({bool c = true, bool a}) {}
+}
+
+class A1 {
+ foo({bool a = true, bool c}) {}
+}
+
+class B1 extends A1 {
+ foo({a = true, bool c}) {}
+}
+
+class C1 extends B1 {
+ foo({bool a = true, bool c}) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/override_inference_named_parameters_ordering.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/override_inference_named_parameters_ordering.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ef3a56b
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_inference_named_parameters_ordering.dart.textual_outline_modelled.expect
@@ -0,0 +1,25 @@
+class A {
+ foo({bool c = true, bool a}) {}
+}
+
+class A1 {
+ foo({bool a = true, bool c}) {}
+}
+
+class B extends A {
+ foo({c = true, bool a}) {}
+}
+
+class B1 extends A1 {
+ foo({a = true, bool c}) {}
+}
+
+class C extends B {
+ foo({bool c = true, bool a}) {}
+}
+
+class C1 extends B1 {
+ foo({bool a = true, bool c}) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/override_setter_with_field.dart.textual_outline.expect b/pkg/front_end/testcases/general/override_setter_with_field.dart.textual_outline.expect
new file mode 100644
index 0000000..e605f98
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_setter_with_field.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+abstract class A {
+ void set x(Object y);
+}
+
+class B implements A {
+ int x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/override_setter_with_field.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/override_setter_with_field.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e605f98
--- /dev/null
+++ b/pkg/front_end/testcases/general/override_setter_with_field.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+abstract class A {
+ void set x(Object y);
+}
+
+class B implements A {
+ int x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/part_as_entry_point.dart.textual_outline.expect b/pkg/front_end/testcases/general/part_as_entry_point.dart.textual_outline.expect
new file mode 100644
index 0000000..07ab488
--- /dev/null
+++ b/pkg/front_end/testcases/general/part_as_entry_point.dart.textual_outline.expect
@@ -0,0 +1 @@
+part of "part_as_entry_point_lib.dart";
diff --git a/pkg/front_end/testcases/general/part_as_entry_point.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/part_as_entry_point.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..07ab488
--- /dev/null
+++ b/pkg/front_end/testcases/general/part_as_entry_point.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+part of "part_as_entry_point_lib.dart";
diff --git a/pkg/front_end/testcases/general/part_not_part_of.dart.textual_outline.expect b/pkg/front_end/testcases/general/part_not_part_of.dart.textual_outline.expect
new file mode 100644
index 0000000..d7c7da3
--- /dev/null
+++ b/pkg/front_end/testcases/general/part_not_part_of.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'part_not_part_of_lib2.dart';
+@override
+part 'part_not_part_of_lib1.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/part_not_part_of.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/part_not_part_of.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d7c7da3
--- /dev/null
+++ b/pkg/front_end/testcases/general/part_not_part_of.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import 'part_not_part_of_lib2.dart';
+@override
+part 'part_not_part_of_lib1.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/part_not_part_of_same_named_library.dart.textual_outline.expect b/pkg/front_end/testcases/general/part_not_part_of_same_named_library.dart.textual_outline.expect
new file mode 100644
index 0000000..bf4aa7d
--- /dev/null
+++ b/pkg/front_end/testcases/general/part_not_part_of_same_named_library.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'part_not_part_of_same_named_library_lib2.dart';
+@override
+part 'part_not_part_of_same_named_library_lib1.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/part_not_part_of_same_named_library.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/part_not_part_of_same_named_library.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bf4aa7d
--- /dev/null
+++ b/pkg/front_end/testcases/general/part_not_part_of_same_named_library.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import 'part_not_part_of_same_named_library_lib2.dart';
+@override
+part 'part_not_part_of_same_named_library_lib1.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/part_part_of_different_unnamed_library.dart.textual_outline.expect b/pkg/front_end/testcases/general/part_part_of_different_unnamed_library.dart.textual_outline.expect
new file mode 100644
index 0000000..a400a31
--- /dev/null
+++ b/pkg/front_end/testcases/general/part_part_of_different_unnamed_library.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'part_part_of_different_unnamed_library_lib2.dart';
+@override
+part 'part_part_of_different_unnamed_library_lib1.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/part_part_of_different_unnamed_library.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/part_part_of_different_unnamed_library.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a400a31
--- /dev/null
+++ b/pkg/front_end/testcases/general/part_part_of_different_unnamed_library.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import 'part_part_of_different_unnamed_library_lib2.dart';
+@override
+part 'part_part_of_different_unnamed_library_lib1.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/part_part_of_differently_named_library.dart.textual_outline.expect b/pkg/front_end/testcases/general/part_part_of_differently_named_library.dart.textual_outline.expect
new file mode 100644
index 0000000..2897172
--- /dev/null
+++ b/pkg/front_end/testcases/general/part_part_of_differently_named_library.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library foo;
+
+import 'part_part_of_differently_named_library_lib2.dart';
+@override
+part 'part_part_of_differently_named_library_lib1.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/part_part_of_differently_named_library.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/part_part_of_differently_named_library.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2897172
--- /dev/null
+++ b/pkg/front_end/testcases/general/part_part_of_differently_named_library.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library foo;
+
+import 'part_part_of_differently_named_library_lib2.dart';
+@override
+part 'part_part_of_differently_named_library_lib1.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/platform.dart.textual_outline.expect b/pkg/front_end/testcases/general/platform.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/platform.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/platform.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/platform.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/general/platform.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/general/platform_invalid_uris/main.dart.textual_outline.expect b/pkg/front_end/testcases/general/platform_invalid_uris/main.dart.textual_outline.expect
new file mode 100644
index 0000000..3c9c90e
--- /dev/null
+++ b/pkg/front_end/testcases/general/platform_invalid_uris/main.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+import 'dart:test';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/platform_invalid_uris/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/platform_invalid_uris/main.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3c9c90e
--- /dev/null
+++ b/pkg/front_end/testcases/general/platform_invalid_uris/main.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+import 'dart:test';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/prefer_baseclass.dart.textual_outline.expect b/pkg/front_end/testcases/general/prefer_baseclass.dart.textual_outline.expect
new file mode 100644
index 0000000..27c1d98
--- /dev/null
+++ b/pkg/front_end/testcases/general/prefer_baseclass.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+class A {}
+
+class B {}
+
+class AB1 extends A implements B {}
+
+class AB2 extends A implements B {}
+
+class BA1 extends B implements A {}
+
+class BA2 extends B implements A {}
+
+takeSubclassOfA(obj) {}
+takeSubclassOfB(obj) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/prefer_baseclass.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/prefer_baseclass.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..47e2b29
--- /dev/null
+++ b/pkg/front_end/testcases/general/prefer_baseclass.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+class A {}
+
+class AB1 extends A implements B {}
+
+class AB2 extends A implements B {}
+
+class B {}
+
+class BA1 extends B implements A {}
+
+class BA2 extends B implements A {}
+
+main() {}
+takeSubclassOfA(obj) {}
+takeSubclassOfB(obj) {}
diff --git a/pkg/front_end/testcases/general/private_method_tearoff.dart.textual_outline.expect b/pkg/front_end/testcases/general/private_method_tearoff.dart.textual_outline.expect
new file mode 100644
index 0000000..929342c
--- /dev/null
+++ b/pkg/front_end/testcases/general/private_method_tearoff.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+import './private_method_tearoff_lib.dart';
+
+class Foo implements Bar {}
+
+class Baz extends Foo {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/private_method_tearoff.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/private_method_tearoff.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2092d9c
--- /dev/null
+++ b/pkg/front_end/testcases/general/private_method_tearoff.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+import './private_method_tearoff_lib.dart';
+
+class Baz extends Foo {}
+
+class Foo implements Bar {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/promoted_access.dart.textual_outline.expect b/pkg/front_end/testcases/general/promoted_access.dart.textual_outline.expect
new file mode 100644
index 0000000..e0aa09a
--- /dev/null
+++ b/pkg/front_end/testcases/general/promoted_access.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class Class<T> {
+ method(T o) {}
+}
+
+method<T>(T o) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/promoted_access.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/promoted_access.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..35276e6
--- /dev/null
+++ b/pkg/front_end/testcases/general/promoted_access.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class Class<T> {
+ method(T o) {}
+}
+
+main() {}
+method<T>(T o) {}
diff --git a/pkg/front_end/testcases/general/promoted_null_aware_access.dart.textual_outline.expect b/pkg/front_end/testcases/general/promoted_null_aware_access.dart.textual_outline.expect
new file mode 100644
index 0000000..2ed1e94
--- /dev/null
+++ b/pkg/front_end/testcases/general/promoted_null_aware_access.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+method<T>(T o) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/promoted_null_aware_access.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/promoted_null_aware_access.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8fa980e
--- /dev/null
+++ b/pkg/front_end/testcases/general/promoted_null_aware_access.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+main() {}
+method<T>(T o) {}
diff --git a/pkg/front_end/testcases/general/public_method_tearoff.dart.textual_outline.expect b/pkg/front_end/testcases/general/public_method_tearoff.dart.textual_outline.expect
new file mode 100644
index 0000000..e266da1
--- /dev/null
+++ b/pkg/front_end/testcases/general/public_method_tearoff.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import './public_method_tearoff_lib.dart';
+
+class Foo extends Bar {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/public_method_tearoff.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/public_method_tearoff.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e266da1
--- /dev/null
+++ b/pkg/front_end/testcases/general/public_method_tearoff.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import './public_method_tearoff_lib.dart';
+
+class Foo extends Bar {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/qualified.dart.textual_outline.expect b/pkg/front_end/testcases/general/qualified.dart.textual_outline.expect
new file mode 100644
index 0000000..accfab2
--- /dev/null
+++ b/pkg/front_end/testcases/general/qualified.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test.qualified.main;
+
+import "qualified_lib.dart" as lib;
+part "qualified_part.dart";
+
+class Bad extends lib.Missing {
+ lib.Missing method() {}
+ factory WrongName() {}
+}
+
+class WithMixin extends lib.Supertype with lib.Mixin {}
+
+class IllegalSupertype extends lib.VoidFunction {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/qualified.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/qualified.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0713429
--- /dev/null
+++ b/pkg/front_end/testcases/general/qualified.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test.qualified.main;
+
+import "qualified_lib.dart" as lib;
+part "qualified_part.dart";
+
+class Bad extends lib.Missing {
+ factory WrongName() {}
+ lib.Missing method() {}
+}
+
+class IllegalSupertype extends lib.VoidFunction {}
+
+class WithMixin extends lib.Supertype with lib.Mixin {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_constructor.dart.textual_outline.expect b/pkg/front_end/testcases/general/redirecting_constructor.dart.textual_outline.expect
new file mode 100644
index 0000000..2e2eb1f
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_constructor.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+class A {
+ A();
+ factory A.fisk() = B;
+}
+
+class B extends A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_constructor.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/redirecting_constructor.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2e2eb1f
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_constructor.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+class A {
+ A();
+ factory A.fisk() = B;
+}
+
+class B extends A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_factory.dart.textual_outline.expect b/pkg/front_end/testcases/general/redirecting_factory.dart.textual_outline.expect
new file mode 100644
index 0000000..b6e0d0a
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_factory.dart.textual_outline.expect
@@ -0,0 +1,34 @@
+abstract class FooBase<Tf> {
+ int get x;
+ factory FooBase(int x) = Foo<Tf>;
+}
+
+abstract class Foo<T> implements FooBase {
+ factory Foo(int x) = Bar<String, T>;
+}
+
+class Bar<Sb, Tb> implements Foo<Tb> {
+ int x;
+ Bar(this.x) {}
+}
+
+class Builder<X> {
+ method() {}
+}
+
+class SimpleCase<A, B> {
+ factory SimpleCase() = SimpleCaseImpl<A, B>;
+}
+
+class SimpleCaseImpl<Ai, Bi> implements SimpleCase<Ai, Bi> {
+ factory SimpleCaseImpl() = SimpleCaseImpl2<Ai, Bi>;
+}
+
+class SimpleCaseImpl2<Ai2, Bi2> implements SimpleCaseImpl<Ai2, Bi2> {}
+
+class Base<M> {}
+
+class Mixin<M> {}
+
+class Mix<M> = Base<M> with Mixin<M>;
+main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_factory.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/redirecting_factory.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bd93039
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_factory.dart.textual_outline_modelled.expect
@@ -0,0 +1,34 @@
+abstract class Foo<T> implements FooBase {
+ factory Foo(int x) = Bar<String, T>;
+}
+
+abstract class FooBase<Tf> {
+ factory FooBase(int x) = Foo<Tf>;
+ int get x;
+}
+
+class Bar<Sb, Tb> implements Foo<Tb> {
+ Bar(this.x) {}
+ int x;
+}
+
+class Base<M> {}
+
+class Builder<X> {
+ method() {}
+}
+
+class Mixin<M> {}
+
+class SimpleCase<A, B> {
+ factory SimpleCase() = SimpleCaseImpl<A, B>;
+}
+
+class SimpleCaseImpl2<Ai2, Bi2> implements SimpleCaseImpl<Ai2, Bi2> {}
+
+class SimpleCaseImpl<Ai, Bi> implements SimpleCase<Ai, Bi> {
+ factory SimpleCaseImpl() = SimpleCaseImpl2<Ai, Bi>;
+}
+
+class Mix<M> = Base<M> with Mixin<M>;
+main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_factory_chain_test.dart.textual_outline.expect b/pkg/front_end/testcases/general/redirecting_factory_chain_test.dart.textual_outline.expect
new file mode 100644
index 0000000..f7ca084
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_factory_chain_test.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library redirecting_factory_constructors.chain_test;
+
+class A {
+ A();
+ factory A.first() = A;
+ factory A.second() = A.first;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_factory_chain_test.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/redirecting_factory_chain_test.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f7ca084
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_factory_chain_test.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library redirecting_factory_constructors.chain_test;
+
+class A {
+ A();
+ factory A.first() = A;
+ factory A.second() = A.first;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_factory_const_inference.dart.textual_outline.expect b/pkg/front_end/testcases/general/redirecting_factory_const_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..1eae718
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_factory_const_inference.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+class _X<T> {
+ const factory _X() = _Y<T>;
+}
+
+class _Y<T> implements _X<T> {
+ const _Y();
+}
+
+class A<T> {
+ _X<T> x;
+ A(this.x);
+}
+
+class B<T> extends A<T> {
+ B() : super(const _X());
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_factory_const_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/redirecting_factory_const_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..71b737f
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_factory_const_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+class A<T> {
+ A(this.x);
+ _X<T> x;
+}
+
+class B<T> extends A<T> {
+ B() : super(const _X());
+}
+
+class _X<T> {
+ const factory _X() = _Y<T>;
+}
+
+class _Y<T> implements _X<T> {
+ const _Y();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_factory_metadata.dart.textual_outline.expect b/pkg/front_end/testcases/general/redirecting_factory_metadata.dart.textual_outline.expect
new file mode 100644
index 0000000..d486790
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_factory_metadata.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+const forParameter = 1;
+const forFactoryItself = 2;
+const anotherForParameter = 3;
+
+class Foo {
+ @forFactoryItself
+ factory Foo(@forParameter @anotherForParameter p) = Foo.named;
+ Foo.named(p);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_factory_metadata.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/redirecting_factory_metadata.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5455e6c
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_factory_metadata.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+class Foo {
+ @forFactoryItself
+ factory Foo(@forParameter @anotherForParameter p) = Foo.named;
+ Foo.named(p);
+}
+
+const anotherForParameter = 3;
+const forFactoryItself = 2;
+const forParameter = 1;
+main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_factory_simple_test.dart.textual_outline.expect b/pkg/front_end/testcases/general/redirecting_factory_simple_test.dart.textual_outline.expect
new file mode 100644
index 0000000..bbefe2c
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_factory_simple_test.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library redirecting_factory_constructors.simple_test;
+
+class A {
+ A();
+ factory A.redir() = A;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_factory_simple_test.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/redirecting_factory_simple_test.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bbefe2c
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_factory_simple_test.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library redirecting_factory_constructors.simple_test;
+
+class A {
+ A();
+ factory A.redir() = A;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_factory_typeargs_test.dart.textual_outline.expect b/pkg/front_end/testcases/general/redirecting_factory_typeargs_test.dart.textual_outline.expect
new file mode 100644
index 0000000..50ddae4
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_factory_typeargs_test.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+library redirecting_factory_constructors.typeargs_test;
+
+class X {}
+
+class Y extends X {}
+
+class A {
+ A();
+ factory A.redir() = B<Y>;
+}
+
+class B<T extends X> extends A {
+ B();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_factory_typeargs_test.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/redirecting_factory_typeargs_test.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d52aa92
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_factory_typeargs_test.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+library redirecting_factory_constructors.typeargs_test;
+
+class A {
+ A();
+ factory A.redir() = B<Y>;
+}
+
+class B<T extends X> extends A {
+ B();
+}
+
+class X {}
+
+class Y extends X {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_factory_typeparam_test.dart.textual_outline.expect b/pkg/front_end/testcases/general/redirecting_factory_typeparam_test.dart.textual_outline.expect
new file mode 100644
index 0000000..e04255c
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_factory_typeparam_test.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library redirecting_factory_constructors.typeparam_test;
+
+class A<T, S> {
+ A(T t, S s);
+ factory A.redir(T t, S s) = A<T, S>;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_factory_typeparam_test.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/redirecting_factory_typeparam_test.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e04255c
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_factory_typeparam_test.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library redirecting_factory_constructors.typeparam_test;
+
+class A<T, S> {
+ A(T t, S s);
+ factory A.redir(T t, S s) = A<T, S>;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_factory_typeparambounds_test.dart.textual_outline.expect b/pkg/front_end/testcases/general/redirecting_factory_typeparambounds_test.dart.textual_outline.expect
new file mode 100644
index 0000000..e6ad16e
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_factory_typeparambounds_test.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library redirecting_factory_constructors.typeparambounds_test;
+
+class X {}
+
+class Y extends X {}
+
+class A<T, S extends T> {
+ A(T t, S s);
+ factory A.redir(T t, S s) = A<T, S>;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_factory_typeparambounds_test.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/redirecting_factory_typeparambounds_test.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..036a788
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_factory_typeparambounds_test.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library redirecting_factory_constructors.typeparambounds_test;
+
+class A<T, S extends T> {
+ A(T t, S s);
+ factory A.redir(T t, S s) = A<T, S>;
+}
+
+class X {}
+
+class Y extends X {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_initializer_arguments_assignable_test.dart.textual_outline.expect b/pkg/front_end/testcases/general/redirecting_initializer_arguments_assignable_test.dart.textual_outline.expect
new file mode 100644
index 0000000..1de1d30
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_initializer_arguments_assignable_test.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class X {}
+
+class Foo<T extends X> {
+ T x;
+ Foo.fromX(X _init) : this._internal(x: _init);
+ Foo.fromT(T _init) : this._internal(x: _init);
+ Foo._internal({this.x});
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_initializer_arguments_assignable_test.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/redirecting_initializer_arguments_assignable_test.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f132422
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_initializer_arguments_assignable_test.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+class Foo<T extends X> {
+ Foo._internal({this.x});
+ Foo.fromT(T _init) : this._internal(x: _init);
+ Foo.fromX(X _init) : this._internal(x: _init);
+ T x;
+}
+
+class X {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_initializer_arguments_test.dart.textual_outline.expect b/pkg/front_end/testcases/general/redirecting_initializer_arguments_test.dart.textual_outline.expect
new file mode 100644
index 0000000..67a67e9
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_initializer_arguments_test.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class Foo<T> {
+ T x;
+ Foo.from(String _init) : this._internal(x: _init);
+ Foo._internal({this.x});
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/redirecting_initializer_arguments_test.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/redirecting_initializer_arguments_test.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9b96053
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirecting_initializer_arguments_test.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class Foo<T> {
+ Foo._internal({this.x});
+ Foo.from(String _init) : this._internal(x: _init);
+ T x;
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/redirection_chain_type_arguments.dart.textual_outline.expect b/pkg/front_end/testcases/general/redirection_chain_type_arguments.dart.textual_outline.expect
new file mode 100644
index 0000000..772fcd2
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirection_chain_type_arguments.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+import 'package:expect/expect.dart';
+
+class A<T> {
+ factory A() = B<T, num>;
+ A.empty();
+}
+
+class B<U, W> extends A<U> {
+ factory B() = C<U, W, String>;
+ B.empty() : super.empty();
+}
+
+class C<V, S, R> extends B<V, S> {
+ C() : super.empty();
+ toString() => "${V},${S},${R}";
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/redirection_chain_type_arguments.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/redirection_chain_type_arguments.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6f267ca
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirection_chain_type_arguments.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+import 'package:expect/expect.dart';
+
+class A<T> {
+ A.empty();
+ factory A() = B<T, num>;
+}
+
+class B<U, W> extends A<U> {
+ B.empty() : super.empty();
+ factory B() = C<U, W, String>;
+}
+
+class C<V, S, R> extends B<V, S> {
+ C() : super.empty();
+ toString() => "${V},${S},${R}";
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/redirection_chain_type_arguments_subst.dart.textual_outline.expect b/pkg/front_end/testcases/general/redirection_chain_type_arguments_subst.dart.textual_outline.expect
new file mode 100644
index 0000000..29e8862
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirection_chain_type_arguments_subst.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+import 'package:expect/expect.dart';
+
+abstract class A<T> {
+ factory A() = B<T, List<T>>;
+ A.empty();
+}
+
+abstract class B<U, W> extends A<U> {
+ factory B() = C<U, W, Map<U, W>>;
+ B.empty() : super.empty();
+}
+
+class C<V, S, R> extends B<V, S> {
+ C() : super.empty();
+ toString() => "${V},${S},${R}";
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/redirection_chain_type_arguments_subst.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/redirection_chain_type_arguments_subst.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7040eb4
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirection_chain_type_arguments_subst.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+import 'package:expect/expect.dart';
+
+abstract class A<T> {
+ A.empty();
+ factory A() = B<T, List<T>>;
+}
+
+abstract class B<U, W> extends A<U> {
+ B.empty() : super.empty();
+ factory B() = C<U, W, Map<U, W>>;
+}
+
+class C<V, S, R> extends B<V, S> {
+ C() : super.empty();
+ toString() => "${V},${S},${R}";
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/redirection_type_arguments.dart.textual_outline.expect b/pkg/front_end/testcases/general/redirection_type_arguments.dart.textual_outline.expect
new file mode 100644
index 0000000..10ae984
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirection_type_arguments.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+import 'package:expect/expect.dart';
+
+class A {
+ const factory A() = B<String>;
+ const A.empty();
+}
+
+class B<T> extends A {
+ const B() : super.empty();
+ toString() => '${T}';
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/redirection_type_arguments.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/redirection_type_arguments.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..561ace4
--- /dev/null
+++ b/pkg/front_end/testcases/general/redirection_type_arguments.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+import 'package:expect/expect.dart';
+
+class A {
+ const A.empty();
+ const factory A() = B<String>;
+}
+
+class B<T> extends A {
+ const B() : super.empty();
+ toString() => '${T}';
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/reject_generic_function_types_in_bounds.dart.textual_outline.expect b/pkg/front_end/testcases/general/reject_generic_function_types_in_bounds.dart.textual_outline.expect
new file mode 100644
index 0000000..27c53cf
--- /dev/null
+++ b/pkg/front_end/testcases/general/reject_generic_function_types_in_bounds.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+class Hest<TypeX extends TypeY Function<TypeY>(TypeY)> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/reject_generic_function_types_in_bounds.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/reject_generic_function_types_in_bounds.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..27c53cf
--- /dev/null
+++ b/pkg/front_end/testcases/general/reject_generic_function_types_in_bounds.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+class Hest<TypeX extends TypeY Function<TypeY>(TypeY)> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/return_with_unknown_type_in_context.dart.textual_outline.expect b/pkg/front_end/testcases/general/return_with_unknown_type_in_context.dart.textual_outline.expect
new file mode 100644
index 0000000..fcee7cc
--- /dev/null
+++ b/pkg/front_end/testcases/general/return_with_unknown_type_in_context.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+bool f(List x) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/return_with_unknown_type_in_context.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/return_with_unknown_type_in_context.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fcee7cc
--- /dev/null
+++ b/pkg/front_end/testcases/general/return_with_unknown_type_in_context.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+bool f(List x) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/sdk_diagnostic.dart.textual_outline.expect b/pkg/front_end/testcases/general/sdk_diagnostic.dart.textual_outline.expect
new file mode 100644
index 0000000..1a2b8fa
--- /dev/null
+++ b/pkg/front_end/testcases/general/sdk_diagnostic.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class C extends Iterable<Object> {}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/sdk_diagnostic.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/sdk_diagnostic.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..23c1a60
--- /dev/null
+++ b/pkg/front_end/testcases/general/sdk_diagnostic.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+class C extends Iterable<Object> {}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/spread_collection.dart.textual_outline.expect b/pkg/front_end/testcases/general/spread_collection.dart.textual_outline.expect
new file mode 100644
index 0000000..a527799
--- /dev/null
+++ b/pkg/front_end/testcases/general/spread_collection.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+main() {}
+foo() => null;
diff --git a/pkg/front_end/testcases/general/spread_collection.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/spread_collection.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d461a14
--- /dev/null
+++ b/pkg/front_end/testcases/general/spread_collection.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+foo() => null;
+main() {}
diff --git a/pkg/front_end/testcases/general/spread_collection_inference.dart.textual_outline.expect b/pkg/front_end/testcases/general/spread_collection_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..5ebffd1
--- /dev/null
+++ b/pkg/front_end/testcases/general/spread_collection_inference.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+Map<K, V> bar<K, V>() => null;
+foo(dynamic dynVar) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/spread_collection_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/spread_collection_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5ebffd1
--- /dev/null
+++ b/pkg/front_end/testcases/general/spread_collection_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+Map<K, V> bar<K, V>() => null;
+foo(dynamic dynVar) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/statements.dart.textual_outline.expect b/pkg/front_end/testcases/general/statements.dart.textual_outline.expect
new file mode 100644
index 0000000..cec9847
--- /dev/null
+++ b/pkg/front_end/testcases/general/statements.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+foo() {}
+bar() async {}
+main() {}
diff --git a/pkg/front_end/testcases/general/statements.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/statements.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6c4d710
--- /dev/null
+++ b/pkg/front_end/testcases/general/statements.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+bar() async {}
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/static_setter.dart.textual_outline.expect b/pkg/front_end/testcases/general/static_setter.dart.textual_outline.expect
new file mode 100644
index 0000000..e45f3a8
--- /dev/null
+++ b/pkg/front_end/testcases/general/static_setter.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class Foo {}
+
+set foo(x) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/static_setter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/static_setter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cad463e
--- /dev/null
+++ b/pkg/front_end/testcases/general/static_setter.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+class Foo {}
+
+main() {}
+set foo(x) {}
diff --git a/pkg/front_end/testcases/general/store_load.dart.textual_outline.expect b/pkg/front_end/testcases/general/store_load.dart.textual_outline.expect
new file mode 100644
index 0000000..12677c1
--- /dev/null
+++ b/pkg/front_end/testcases/general/store_load.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+class Foo {
+ var _field;
+}
+
+class FooValue {}
+
+class Bar {
+ var _field;
+}
+
+class BarValue {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/store_load.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/store_load.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d24c44c
--- /dev/null
+++ b/pkg/front_end/testcases/general/store_load.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+class Bar {
+ var _field;
+}
+
+class BarValue {}
+
+class Foo {
+ var _field;
+}
+
+class FooValue {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/stringliteral.dart.textual_outline.expect b/pkg/front_end/testcases/general/stringliteral.dart.textual_outline.expect
new file mode 100644
index 0000000..203a809
--- /dev/null
+++ b/pkg/front_end/testcases/general/stringliteral.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+var color = 'brown';
+var thing = 'lazy dog';
+var phrase = "The quick $color fox\njumped over the $thing.\n";
+var adjacent = '$color$color$color';
+var linebreaks = '$color\n$color\n$color';
+var other = '$color\n is \n$color';
+main() {}
diff --git a/pkg/front_end/testcases/general/stringliteral.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/stringliteral.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5ef0a48
--- /dev/null
+++ b/pkg/front_end/testcases/general/stringliteral.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+main() {}
+var adjacent = '$color$color$color';
+var color = 'brown';
+var linebreaks = '$color\n$color\n$color';
+var other = '$color\n is \n$color';
+var phrase = "The quick $color fox\njumped over the $thing.\n";
+var thing = 'lazy dog';
diff --git a/pkg/front_end/testcases/general/super_call.dart.textual_outline.expect b/pkg/front_end/testcases/general/super_call.dart.textual_outline.expect
new file mode 100644
index 0000000..08fd0e2
--- /dev/null
+++ b/pkg/front_end/testcases/general/super_call.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class A {
+ int call(int x) => x * 2;
+}
+
+class B extends A {
+ int call(int x) => x * 3;
+ int call_super() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/super_call.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/super_call.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..08fd0e2
--- /dev/null
+++ b/pkg/front_end/testcases/general/super_call.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+class A {
+ int call(int x) => x * 2;
+}
+
+class B extends A {
+ int call(int x) => x * 3;
+ int call_super() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/super_nsm.dart.textual_outline.expect b/pkg/front_end/testcases/general/super_nsm.dart.textual_outline.expect
new file mode 100644
index 0000000..39c0416
--- /dev/null
+++ b/pkg/front_end/testcases/general/super_nsm.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+abstract class I {
+ interfaceMethod();
+}
+
+class C implements I {
+ noSuchMethod(_) => "C";
+}
+
+class D extends C {
+ noSuchMethod(_) => "D";
+ dMethod() => super.interfaceMethod();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/super_nsm.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/super_nsm.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8dcf482
--- /dev/null
+++ b/pkg/front_end/testcases/general/super_nsm.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+abstract class I {
+ interfaceMethod();
+}
+
+class C implements I {
+ noSuchMethod(_) => "C";
+}
+
+class D extends C {
+ dMethod() => super.interfaceMethod();
+ noSuchMethod(_) => "D";
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/tabs.dart.textual_outline.expect b/pkg/front_end/testcases/general/tabs.dart.textual_outline.expect
new file mode 100644
index 0000000..ec6b9e0
--- /dev/null
+++ b/pkg/front_end/testcases/general/tabs.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/tabs.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/tabs.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f67dbb0
--- /dev/null
+++ b/pkg/front_end/testcases/general/tabs.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general/this_field_call.dart.textual_outline.expect b/pkg/front_end/testcases/general/this_field_call.dart.textual_outline.expect
new file mode 100644
index 0000000..eb3e361
--- /dev/null
+++ b/pkg/front_end/testcases/general/this_field_call.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class A<T> {
+ void Function(T) f;
+ A(this.f);
+ foo(T x) => this.f(x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/this_field_call.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/this_field_call.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b5116cc
--- /dev/null
+++ b/pkg/front_end/testcases/general/this_field_call.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class A<T> {
+ A(this.f);
+ foo(T x) => this.f(x);
+ void Function(T) f;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/three_typedefs_loop.dart.textual_outline.expect b/pkg/front_end/testcases/general/three_typedefs_loop.dart.textual_outline.expect
new file mode 100644
index 0000000..0e6af39
--- /dev/null
+++ b/pkg/front_end/testcases/general/three_typedefs_loop.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+typedef Foo<T> = void Function(Bar<T>);
+typedef Bar<T> = void Function(Baz<T>);
+typedef Baz<T> = void Function(Foo<T>);
+main() {}
diff --git a/pkg/front_end/testcases/general/three_typedefs_loop.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/three_typedefs_loop.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d241b1c
--- /dev/null
+++ b/pkg/front_end/testcases/general/three_typedefs_loop.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+main() {}
+typedef Bar<T> = void Function(Baz<T>);
+typedef Baz<T> = void Function(Foo<T>);
+typedef Foo<T> = void Function(Bar<T>);
diff --git a/pkg/front_end/testcases/general/top_level_accessors.dart.textual_outline.expect b/pkg/front_end/testcases/general/top_level_accessors.dart.textual_outline.expect
new file mode 100644
index 0000000..184dba8
--- /dev/null
+++ b/pkg/front_end/testcases/general/top_level_accessors.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library top_level_accessors;
+
+part 'top_level_accessors_part.dart';
diff --git a/pkg/front_end/testcases/general/top_level_accessors.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/top_level_accessors.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..184dba8
--- /dev/null
+++ b/pkg/front_end/testcases/general/top_level_accessors.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library top_level_accessors;
+
+part 'top_level_accessors_part.dart';
diff --git a/pkg/front_end/testcases/general/top_level_library_method.dart.textual_outline.expect b/pkg/front_end/testcases/general/top_level_library_method.dart.textual_outline.expect
new file mode 100644
index 0000000..e6ec156
--- /dev/null
+++ b/pkg/front_end/testcases/general/top_level_library_method.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+library() {}
+main() => library();
diff --git a/pkg/front_end/testcases/general/top_level_library_method.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/top_level_library_method.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e6ec156
--- /dev/null
+++ b/pkg/front_end/testcases/general/top_level_library_method.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+library() {}
+main() => library();
diff --git a/pkg/front_end/testcases/general/type_literal_as_metadata.dart.textual_outline.expect b/pkg/front_end/testcases/general/type_literal_as_metadata.dart.textual_outline.expect
new file mode 100644
index 0000000..54f0474
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_literal_as_metadata.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+class A {
+ const A();
+}
+
+@A
+class B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/type_literal_as_metadata.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/type_literal_as_metadata.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4127317
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_literal_as_metadata.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+@A
+class B {}
+
+class A {
+ const A();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/type_of_null.dart.textual_outline.expect b/pkg/front_end/testcases/general/type_of_null.dart.textual_outline.expect
new file mode 100644
index 0000000..f8de85e
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_of_null.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+T map<T>(T Function() f1, T Function() f2) {}
+id<T>(T t) => t;
+Null foo() => null;
+main() {}
diff --git a/pkg/front_end/testcases/general/type_of_null.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/type_of_null.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..28d7893
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_of_null.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+Null foo() => null;
+T map<T>(T Function() f1, T Function() f2) {}
+id<T>(T t) => t;
+main() {}
diff --git a/pkg/front_end/testcases/general/type_parameter_type_named_int.dart.textual_outline.expect b/pkg/front_end/testcases/general/type_parameter_type_named_int.dart.textual_outline.expect
new file mode 100644
index 0000000..84e0e68
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_parameter_type_named_int.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+abstract class Foo<T> {
+ List<T> get list;
+ void setList<T>(List<T> value);
+}
+
+class Bar implements Foo<int> {
+ List<int> list;
+ void setList<int>(List<int> value) {}
+}
diff --git a/pkg/front_end/testcases/general/type_parameter_type_named_int.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/type_parameter_type_named_int.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..84e0e68
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_parameter_type_named_int.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+abstract class Foo<T> {
+ List<T> get list;
+ void setList<T>(List<T> value);
+}
+
+class Bar implements Foo<int> {
+ List<int> list;
+ void setList<int>(List<int> value) {}
+}
diff --git a/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_class.dart.textual_outline.expect b/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_class.dart.textual_outline.expect
new file mode 100644
index 0000000..dab722e
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_class.dart.textual_outline.expect
@@ -0,0 +1,24 @@
+class Foo<U> {
+ static U foo1() {}
+ static List<U> foo1Prime() {}
+ static void foo2(U x) {}
+ static void foo2Prime(List<U> x) {}
+ static void foo3() {}
+ static U Function() foo8() {}
+ static List<U> Function() foo8Prime() {}
+ static void Function(U) foo9() {}
+ static void Function(List<U>) foo9Prime() {}
+ static void foo10(U Function()) {}
+ static void foo10Prime(List<U> Function()) {}
+ static void foo11(void Function(U)) {}
+ static void foo12(void Function(U) b) {}
+ static void foo12Prime(void Function(List<U>) b) {}
+ static void foo13(void Function(U b)) {}
+ static void foo13Prime(void Function(List<U> b)) {}
+ static U foo14 = null;
+ static List<U> foo14Prime = null;
+ static U Function(U) foo15 = null;
+ static List<U> Function(List<U>) foo15Prime = null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_class.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_class.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..531ae41
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_class.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+class Foo<U> {
+ static List<U> Function() foo8Prime() {}
+ static List<U> Function(List<U>) foo15Prime = null;
+ static List<U> foo14Prime = null;
+ static List<U> foo1Prime() {}
+ static U Function() foo8() {}
+ static U Function(U) foo15 = null;
+ static U foo1() {}
+ static U foo14 = null;
+ static void Function(List<U>) foo9Prime() {}
+ static void Function(U) foo9() {}
+ static void foo10(U Function()) {}
+ static void foo10Prime(List<U> Function()) {}
+ static void foo11(void Function(U)) {}
+ static void foo12(void Function(U) b) {}
+ static void foo12Prime(void Function(List<U>) b) {}
+ static void foo13(void Function(U b)) {}
+ static void foo13Prime(void Function(List<U> b)) {}
+ static void foo2(U x) {}
+ static void foo2Prime(List<U> x) {}
+ static void foo3() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_extension.dart.textual_outline.expect b/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_extension.dart.textual_outline.expect
new file mode 100644
index 0000000..cd75193
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_extension.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+extension Foo<U> ( ){ }
+on List (){ }
+main() { }
diff --git a/pkg/front_end/testcases/general/type_parameters_on_dynamic.dart.textual_outline.expect b/pkg/front_end/testcases/general/type_parameters_on_dynamic.dart.textual_outline.expect
new file mode 100644
index 0000000..e628591
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_parameters_on_dynamic.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+dynamic<int> f() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/type_parameters_on_dynamic.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/type_parameters_on_dynamic.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e628591
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_parameters_on_dynamic.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+dynamic<int> f() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/type_parameters_on_void.dart.textual_outline.expect b/pkg/front_end/testcases/general/type_parameters_on_void.dart.textual_outline.expect
new file mode 100644
index 0000000..c9c869a
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_parameters_on_void.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+void<int> f() { }
+main() { }
diff --git a/pkg/front_end/testcases/general/type_variable_as_super.dart.textual_outline.expect b/pkg/front_end/testcases/general/type_variable_as_super.dart.textual_outline.expect
new file mode 100644
index 0000000..1fb7f08
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_variable_as_super.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+abstract class A<T> extends T {}
+
+abstract class B<T> extends T {
+ B();
+}
+
+class C<T> extends T {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/type_variable_as_super.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/type_variable_as_super.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1fb7f08
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_variable_as_super.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+abstract class A<T> extends T {}
+
+abstract class B<T> extends T {
+ B();
+}
+
+class C<T> extends T {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/type_variable_bound_access.dart.textual_outline.expect b/pkg/front_end/testcases/general/type_variable_bound_access.dart.textual_outline.expect
new file mode 100644
index 0000000..d7f2e46
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_variable_bound_access.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+class DynamicClass<T extends dynamic, S extends T> {
+ T field1;
+ T field2;
+ DynamicClass(this.field1, this.field2);
+ method() => field1 * field2;
+}
+
+class NumClass<T extends num, S extends T> {
+ T field1;
+ S field2;
+ NumClass(this.field1, this.field2);
+ num method1() => field1 * field2;
+ num method2() => field1 + field2.length;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/type_variable_bound_access.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/type_variable_bound_access.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b92c57e
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_variable_bound_access.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+class DynamicClass<T extends dynamic, S extends T> {
+ DynamicClass(this.field1, this.field2);
+ T field1;
+ T field2;
+ method() => field1 * field2;
+}
+
+class NumClass<T extends num, S extends T> {
+ NumClass(this.field1, this.field2);
+ S field2;
+ T field1;
+ num method1() => field1 * field2;
+ num method2() => field1 + field2.length;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/type_variable_prefix.dart.textual_outline.expect b/pkg/front_end/testcases/general/type_variable_prefix.dart.textual_outline.expect
new file mode 100644
index 0000000..17664d53
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_variable_prefix.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+import "dart:core" as T;
+
+class C<T> {
+ T.String method() => "Hello, World!";
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/type_variable_prefix.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/type_variable_prefix.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..17664d53
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_variable_prefix.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+import "dart:core" as T;
+
+class C<T> {
+ T.String method() => "Hello, World!";
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/type_variable_uses.dart.textual_outline.expect b/pkg/front_end/testcases/general/type_variable_uses.dart.textual_outline.expect
new file mode 100644
index 0000000..4ea252b
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_variable_uses.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class C<T> {
+ const C();
+ static C<T> staticMethod() {}
+ C<T> instanceMethod() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/type_variable_uses.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/type_variable_uses.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d8414ce
--- /dev/null
+++ b/pkg/front_end/testcases/general/type_variable_uses.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class C<T> {
+ C<T> instanceMethod() {}
+ const C();
+ static C<T> staticMethod() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/typedef.dart.textual_outline.expect b/pkg/front_end/testcases/general/typedef.dart.textual_outline.expect
new file mode 100644
index 0000000..f652ebb
--- /dev/null
+++ b/pkg/front_end/testcases/general/typedef.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+typedef _NullaryFunction();
+typedef _UnaryFunction(args);
+typedef _BinaryFunction(args, message);
+main() {}
diff --git a/pkg/front_end/testcases/general/typedef.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/typedef.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7714b6b
--- /dev/null
+++ b/pkg/front_end/testcases/general/typedef.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+main() {}
+typedef _BinaryFunction(args, message);
+typedef _NullaryFunction();
+typedef _UnaryFunction(args);
diff --git a/pkg/front_end/testcases/general/undefined.dart.textual_outline.expect b/pkg/front_end/testcases/general/undefined.dart.textual_outline.expect
new file mode 100644
index 0000000..7c1f7be
--- /dev/null
+++ b/pkg/front_end/testcases/general/undefined.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class C {
+ var x;
+ void f() {}
+}
+
+void test(C c) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/undefined.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/undefined.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6775e59
--- /dev/null
+++ b/pkg/front_end/testcases/general/undefined.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class C {
+ var x;
+ void f() {}
+}
+
+main() {}
+void test(C c) {}
diff --git a/pkg/front_end/testcases/general/undefined_getter_in_compound_assignment.dart.textual_outline.expect b/pkg/front_end/testcases/general/undefined_getter_in_compound_assignment.dart.textual_outline.expect
new file mode 100644
index 0000000..627bd18
--- /dev/null
+++ b/pkg/front_end/testcases/general/undefined_getter_in_compound_assignment.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class C {
+ void set x(value) {}
+}
+
+void test(C c) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/undefined_getter_in_compound_assignment.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/undefined_getter_in_compound_assignment.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b1044c0
--- /dev/null
+++ b/pkg/front_end/testcases/general/undefined_getter_in_compound_assignment.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class C {
+ void set x(value) {}
+}
+
+main() {}
+void test(C c) {}
diff --git a/pkg/front_end/testcases/general/uninitialized_fields.dart.textual_outline.expect b/pkg/front_end/testcases/general/uninitialized_fields.dart.textual_outline.expect
new file mode 100644
index 0000000..29870cc
--- /dev/null
+++ b/pkg/front_end/testcases/general/uninitialized_fields.dart.textual_outline.expect
@@ -0,0 +1,24 @@
+class Uninitialized {
+ int x;
+}
+
+class PartiallyInitialized {
+ int x;
+ PartiallyInitialized(this.x);
+ PartiallyInitialized.noInitializer();
+}
+
+class Initialized {
+ int x;
+ Initialized(this.x);
+}
+
+class Forwarding {
+ int x;
+ Forwarding.initialize(this.x);
+ Forwarding(int arg) : this.initialize(arg);
+}
+
+int uninitializedTopLevel;
+int initializedTopLevel = 4;
+main() {}
diff --git a/pkg/front_end/testcases/general/uninitialized_fields.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/uninitialized_fields.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a6b77e3
--- /dev/null
+++ b/pkg/front_end/testcases/general/uninitialized_fields.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+class Forwarding {
+ Forwarding(int arg) : this.initialize(arg);
+ Forwarding.initialize(this.x);
+ int x;
+}
+
+class Initialized {
+ Initialized(this.x);
+ int x;
+}
+
+class PartiallyInitialized {
+ PartiallyInitialized(this.x);
+ PartiallyInitialized.noInitializer();
+ int x;
+}
+
+class Uninitialized {
+ int x;
+}
+
+int initializedTopLevel = 4;
+int uninitializedTopLevel;
+main() {}
diff --git a/pkg/front_end/testcases/general/unsound_promotion.dart.textual_outline.expect b/pkg/front_end/testcases/general/unsound_promotion.dart.textual_outline.expect
new file mode 100644
index 0000000..0e5f983
--- /dev/null
+++ b/pkg/front_end/testcases/general/unsound_promotion.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class A {}
+
+class B {}
+
+class C extends B implements A {}
+
+List<A> list;
+List<T> g<T extends A>(T t) {}
+List<S> f<S>(S s) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/unsound_promotion.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/unsound_promotion.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b3488fc
--- /dev/null
+++ b/pkg/front_end/testcases/general/unsound_promotion.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+List<A> list;
+List<S> f<S>(S s) {}
+List<T> g<T extends A>(T t) {}
+
+class A {}
+
+class B {}
+
+class C extends B implements A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/unused_methods.dart.textual_outline.expect b/pkg/front_end/testcases/general/unused_methods.dart.textual_outline.expect
new file mode 100644
index 0000000..d30480d
--- /dev/null
+++ b/pkg/front_end/testcases/general/unused_methods.dart.textual_outline.expect
@@ -0,0 +1,36 @@
+class UnusedClass {
+ UnusedClass() {}
+}
+
+abstract class UsedAsBaseClass {
+ void usedInSubclass() {}
+ void calledFromB() {}
+ void calledFromSubclass() {}
+}
+
+class UsedAsInterface {
+ void usedInSubclass() {}
+}
+
+class InstantiatedButMethodsUnused {
+ void usedInSubclass() {}
+}
+
+class ClassA extends UsedAsBaseClass
+ implements UsedAsInterface, InstantiatedButMethodsUnused {
+ void usedInSubclass() {}
+}
+
+class ClassB extends UsedAsBaseClass
+ implements UsedAsInterface, InstantiatedButMethodsUnused {
+ void usedInSubclass() {}
+ void calledFromSubclass() {}
+}
+
+void baseClassCall(UsedAsBaseClass object) {}
+void interfaceCall(UsedAsInterface object) {}
+void exactCallA(ClassA object) {}
+void exactCallB(ClassB object) {}
+unusedTopLevel() {}
+usedTopLevel() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/unused_methods.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/unused_methods.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fe88e83
--- /dev/null
+++ b/pkg/front_end/testcases/general/unused_methods.dart.textual_outline_modelled.expect
@@ -0,0 +1,36 @@
+abstract class UsedAsBaseClass {
+ void calledFromB() {}
+ void calledFromSubclass() {}
+ void usedInSubclass() {}
+}
+
+class ClassA extends UsedAsBaseClass
+ implements UsedAsInterface, InstantiatedButMethodsUnused {
+ void usedInSubclass() {}
+}
+
+class ClassB extends UsedAsBaseClass
+ implements UsedAsInterface, InstantiatedButMethodsUnused {
+ void calledFromSubclass() {}
+ void usedInSubclass() {}
+}
+
+class InstantiatedButMethodsUnused {
+ void usedInSubclass() {}
+}
+
+class UnusedClass {
+ UnusedClass() {}
+}
+
+class UsedAsInterface {
+ void usedInSubclass() {}
+}
+
+main() {}
+unusedTopLevel() {}
+usedTopLevel() {}
+void baseClassCall(UsedAsBaseClass object) {}
+void exactCallA(ClassA object) {}
+void exactCallB(ClassB object) {}
+void interfaceCall(UsedAsInterface object) {}
diff --git a/pkg/front_end/testcases/general/var_as_type_name.dart.textual_outline.expect b/pkg/front_end/testcases/general/var_as_type_name.dart.textual_outline.expect
new file mode 100644
index 0000000..4852e57
--- /dev/null
+++ b/pkg/front_end/testcases/general/var_as_type_name.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class A {
+ Map<String, var> m;
+}
+main() { }
diff --git a/pkg/front_end/testcases/general/vm_type_ops.dart.textual_outline.expect b/pkg/front_end/testcases/general/vm_type_ops.dart.textual_outline.expect
new file mode 100644
index 0000000..2acf1f6
--- /dev/null
+++ b/pkg/front_end/testcases/general/vm_type_ops.dart.textual_outline.expect
@@ -0,0 +1,38 @@
+class A<T> {}
+
+class B extends A<String> {}
+
+class C<T1, T2, T3> extends B {}
+
+foo1(x) {}
+
+class D<P, Q> extends C<int, Q, P> {
+ Map<P, Q> foo;
+ D(tt) : foo = tt;
+ foo2(y) {}
+ foo3<T1, T2>(z) {}
+ Map<P, Q> foo4(w) {}
+}
+
+List<Iterable> globalVar;
+void foo5(x) {}
+
+class E<P extends String> {
+ factory E() => null;
+ void foo6<T extends P, U extends List<T>>(Map<T, U> map) {}
+}
+
+abstract class F<T> {
+ void foo7<Q extends T>(Q a, covariant num b, T c);
+ void foo8<Q extends T>(Q a, covariant num b, T c);
+}
+
+class G<T> {
+ void foo7<Q extends T>(Q a, int b, T c) {}
+}
+
+class H<T> extends G<T> implements F<T> {
+ void foo8<Q extends T>(Q a, int b, T c) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/vm_type_ops.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/vm_type_ops.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..96d4e65
--- /dev/null
+++ b/pkg/front_end/testcases/general/vm_type_ops.dart.textual_outline_modelled.expect
@@ -0,0 +1,37 @@
+List<Iterable> globalVar;
+
+abstract class F<T> {
+ void foo7<Q extends T>(Q a, covariant num b, T c);
+ void foo8<Q extends T>(Q a, covariant num b, T c);
+}
+
+class A<T> {}
+
+class B extends A<String> {}
+
+class C<T1, T2, T3> extends B {}
+
+class D<P, Q> extends C<int, Q, P> {
+ D(tt) : foo = tt;
+ Map<P, Q> foo4(w) {}
+ Map<P, Q> foo;
+ foo2(y) {}
+ foo3<T1, T2>(z) {}
+}
+
+class E<P extends String> {
+ factory E() => null;
+ void foo6<T extends P, U extends List<T>>(Map<T, U> map) {}
+}
+
+class G<T> {
+ void foo7<Q extends T>(Q a, int b, T c) {}
+}
+
+class H<T> extends G<T> implements F<T> {
+ void foo8<Q extends T>(Q a, int b, T c) {}
+}
+
+foo1(x) {}
+main() {}
+void foo5(x) {}
diff --git a/pkg/front_end/testcases/general/void_methods.dart.textual_outline.expect b/pkg/front_end/testcases/general/void_methods.dart.textual_outline.expect
new file mode 100644
index 0000000..a23d97f
--- /dev/null
+++ b/pkg/front_end/testcases/general/void_methods.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+class Foo {
+ List list = [1, 2, 3];
+ set first(x) => list[0] = x;
+ operator []=(x, y) => list[x] = y;
+ void clear() => list.clear();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/void_methods.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/void_methods.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f5f0084
--- /dev/null
+++ b/pkg/front_end/testcases/general/void_methods.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+class Foo {
+ List list = [1, 2, 3];
+ operator []=(x, y) => list[x] = y;
+ set first(x) => list[0] = x;
+ void clear() => list.clear();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/warn_unresolved_sends.dart.textual_outline.expect b/pkg/front_end/testcases/general/warn_unresolved_sends.dart.textual_outline.expect
new file mode 100644
index 0000000..9862754
--- /dev/null
+++ b/pkg/front_end/testcases/general/warn_unresolved_sends.dart.textual_outline.expect
@@ -0,0 +1,23 @@
+class C {
+ var superField;
+ superMethod() {}
+ get setterOnly => null;
+ void set setterOnly(_) {}
+ get getterOnly => null;
+ void set getterOnly(_) {}
+}
+
+class D extends C {
+ var field;
+ void set setterOnly(_) {}
+ get getterOnly => null;
+ method() {}
+ void test() {}
+}
+
+class E extends D {
+ var missingField;
+ void missingMethod() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/warn_unresolved_sends.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/warn_unresolved_sends.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..73c7281
--- /dev/null
+++ b/pkg/front_end/testcases/general/warn_unresolved_sends.dart.textual_outline_modelled.expect
@@ -0,0 +1,23 @@
+class C {
+ get getterOnly => null;
+ get setterOnly => null;
+ superMethod() {}
+ var superField;
+ void set getterOnly(_) {}
+ void set setterOnly(_) {}
+}
+
+class D extends C {
+ get getterOnly => null;
+ method() {}
+ var field;
+ void set setterOnly(_) {}
+ void test() {}
+}
+
+class E extends D {
+ var missingField;
+ void missingMethod() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/well_boundness_checks_in_outline.dart.textual_outline.expect b/pkg/front_end/testcases/general/well_boundness_checks_in_outline.dart.textual_outline.expect
new file mode 100644
index 0000000..e49eb01
--- /dev/null
+++ b/pkg/front_end/testcases/general/well_boundness_checks_in_outline.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class A<X extends int> {
+}
+class B {
+ A<num> fieldOfA;
+ static A<num> staticFieldOfA;
+}
+extension E<X extends A<num>> ( ){ }
+on A (){ }
+main() { }
diff --git a/pkg/front_end/testcases/general/with_dependencies/abstract_members_from_dill/main.dart.textual_outline.expect b/pkg/front_end/testcases/general/with_dependencies/abstract_members_from_dill/main.dart.textual_outline.expect
new file mode 100644
index 0000000..085740d
--- /dev/null
+++ b/pkg/front_end/testcases/general/with_dependencies/abstract_members_from_dill/main.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'main_lib.dart';
+
+class B extends A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/with_dependencies/abstract_members_from_dill/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/with_dependencies/abstract_members_from_dill/main.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..085740d
--- /dev/null
+++ b/pkg/front_end/testcases/general/with_dependencies/abstract_members_from_dill/main.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import 'main_lib.dart';
+
+class B extends A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/with_dependencies/extension_from_dill/extension_from_dill.dart.textual_outline.expect b/pkg/front_end/testcases/general/with_dependencies/extension_from_dill/extension_from_dill.dart.textual_outline.expect
new file mode 100644
index 0000000..76f9b18
--- /dev/null
+++ b/pkg/front_end/testcases/general/with_dependencies/extension_from_dill/extension_from_dill.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+import 'extension_from_dill_lib.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/with_dependencies/extension_from_dill/extension_from_dill.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/with_dependencies/extension_from_dill/extension_from_dill.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..76f9b18
--- /dev/null
+++ b/pkg/front_end/testcases/general/with_dependencies/extension_from_dill/extension_from_dill.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+import 'extension_from_dill_lib.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general/with_dependencies/variance_from_dill/variance_from_dill.dart.textual_outline.expect b/pkg/front_end/testcases/general/with_dependencies/variance_from_dill/variance_from_dill.dart.textual_outline.expect
new file mode 100644
index 0000000..541fc41
--- /dev/null
+++ b/pkg/front_end/testcases/general/with_dependencies/variance_from_dill/variance_from_dill.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import "variance_from_dill_lib.dart";
+
+typedef G<T> = Function(F<T>);
+main() {}
diff --git a/pkg/front_end/testcases/general/with_dependencies/variance_from_dill/variance_from_dill.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/with_dependencies/variance_from_dill/variance_from_dill.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..17d9aa1
--- /dev/null
+++ b/pkg/front_end/testcases/general/with_dependencies/variance_from_dill/variance_from_dill.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import "variance_from_dill_lib.dart";
+
+main() {}
+typedef G<T> = Function(F<T>);
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/DeltaBlue.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/DeltaBlue.dart.textual_outline.expect
new file mode 100644
index 0000000..55a63ae
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/DeltaBlue.dart.textual_outline.expect
@@ -0,0 +1,154 @@
+// @dart = 2.6
+main() {}
+
+class DeltaBlue {
+ void run() {}
+}
+
+class Strength {
+ final int value;
+ final String name;
+ const Strength(this.value, this.name);
+ Strength nextWeaker() => const <Strength>[
+ STRONG_PREFERRED,
+ PREFERRED,
+ STRONG_DEFAULT,
+ NORMAL,
+ WEAK_DEFAULT,
+ WEAKEST
+ ][value];
+ static bool stronger(Strength s1, Strength s2) {}
+ static bool weaker(Strength s1, Strength s2) {}
+ static Strength weakest(Strength s1, Strength s2) {}
+ static Strength strongest(Strength s1, Strength s2) {}
+}
+
+const REQUIRED = const Strength(0, "required");
+const STRONG_PREFERRED = const Strength(1, "strongPreferred");
+const PREFERRED = const Strength(2, "preferred");
+const STRONG_DEFAULT = const Strength(3, "strongDefault");
+const NORMAL = const Strength(4, "normal");
+const WEAK_DEFAULT = const Strength(5, "weakDefault");
+const WEAKEST = const Strength(6, "weakest");
+
+abstract class Constraint {
+ final Strength strength;
+ const Constraint(this.strength);
+ bool isSatisfied();
+ void markUnsatisfied();
+ void addToGraph();
+ void removeFromGraph();
+ void chooseMethod(int mark);
+ void markInputs(int mark);
+ bool inputsKnown(int mark);
+ Variable output();
+ void execute();
+ void recalculate();
+ void addConstraint() {}
+ Constraint satisfy(mark) {}
+ void destroyConstraint() {}
+ bool isInput() => false;
+}
+
+abstract class UnaryConstraint extends Constraint {
+ final Variable myOutput;
+ bool satisfied = false;
+ UnaryConstraint(this.myOutput, Strength strength) : super(strength) {}
+ void addToGraph() {}
+ void chooseMethod(int mark) {}
+ bool isSatisfied() => satisfied;
+ void markInputs(int mark) {}
+ Variable output() => myOutput;
+ void recalculate() {}
+ void markUnsatisfied() {}
+ bool inputsKnown(int mark) => true;
+ void removeFromGraph() {}
+}
+
+class StayConstraint extends UnaryConstraint {
+ StayConstraint(Variable v, Strength str) : super(v, str);
+ void execute() {}
+}
+
+class EditConstraint extends UnaryConstraint {
+ EditConstraint(Variable v, Strength str) : super(v, str);
+ bool isInput() => true;
+ void execute() {}
+}
+
+const int NONE = 1;
+const int FORWARD = 2;
+const int BACKWARD = 0;
+
+abstract class BinaryConstraint extends Constraint {
+ Variable v1;
+ Variable v2;
+ int direction = NONE;
+ BinaryConstraint(this.v1, this.v2, Strength strength) : super(strength) {}
+ void chooseMethod(int mark) {}
+ void addToGraph() {}
+ bool isSatisfied() => direction != NONE;
+ void markInputs(int mark) {}
+ Variable input() => direction == FORWARD ? v1 : v2;
+ Variable output() => direction == FORWARD ? v2 : v1;
+ void recalculate() {}
+ void markUnsatisfied() {}
+ bool inputsKnown(int mark) {}
+ void removeFromGraph() {}
+}
+
+class ScaleConstraint extends BinaryConstraint {
+ final Variable scale;
+ final Variable offset;
+ ScaleConstraint(
+ Variable src, this.scale, this.offset, Variable dest, Strength strength)
+ : super(src, dest, strength);
+ void addToGraph() {}
+ void removeFromGraph() {}
+ void markInputs(int mark) {}
+ void execute() {}
+ void recalculate() {}
+}
+
+class EqualityConstraint extends BinaryConstraint {
+ EqualityConstraint(Variable v1, Variable v2, Strength strength)
+ : super(v1, v2, strength);
+ void execute() {}
+}
+
+class Variable {
+ List<Constraint> constraints = <Constraint>[];
+ Constraint determinedBy;
+ int mark = 0;
+ Strength walkStrength = WEAKEST;
+ bool stay = true;
+ int value;
+ final String name;
+ Variable(this.name, this.value);
+ void addConstraint(Constraint c) {}
+ void removeConstraint(Constraint c) {}
+}
+
+class Planner {
+ int currentMark = 0;
+ void incrementalAdd(Constraint c) {}
+ void incrementalRemove(Constraint c) {}
+ int newMark() => ++currentMark;
+ Plan makePlan(List<Constraint> sources) {}
+ Plan extractPlanFromConstraints(List<Constraint> constraints) {}
+ bool addPropagate(Constraint c, int mark) {}
+ List<Constraint> removePropagateFrom(Variable out) {}
+ void addConstraintsConsumingTo(Variable v, List<Constraint> coll) {}
+}
+
+class Plan {
+ List<Constraint> list = <Constraint>[];
+ void addConstraint(Constraint c) {}
+ int size() => list.length;
+ void execute() {}
+}
+
+void chainTest(int n) {}
+void projectionTest(int n) {}
+void change(Variable v, int newValue) {}
+Planner planner;
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/DeltaBlue.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/DeltaBlue.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..65dc50b
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/DeltaBlue.dart.textual_outline_modelled.expect
@@ -0,0 +1,152 @@
+// @dart = 2.6
+Planner planner;
+
+abstract class BinaryConstraint extends Constraint {
+ BinaryConstraint(this.v1, this.v2, Strength strength) : super(strength) {}
+ Variable input() => direction == FORWARD ? v1 : v2;
+ Variable output() => direction == FORWARD ? v2 : v1;
+ Variable v1;
+ Variable v2;
+ bool inputsKnown(int mark) {}
+ bool isSatisfied() => direction != NONE;
+ int direction = NONE;
+ void addToGraph() {}
+ void chooseMethod(int mark) {}
+ void markInputs(int mark) {}
+ void markUnsatisfied() {}
+ void recalculate() {}
+ void removeFromGraph() {}
+}
+
+abstract class Constraint {
+ Constraint satisfy(mark) {}
+ Variable output();
+ bool inputsKnown(int mark);
+ bool isInput() => false;
+ bool isSatisfied();
+ const Constraint(this.strength);
+ final Strength strength;
+ void addConstraint() {}
+ void addToGraph();
+ void chooseMethod(int mark);
+ void destroyConstraint() {}
+ void execute();
+ void markInputs(int mark);
+ void markUnsatisfied();
+ void recalculate();
+ void removeFromGraph();
+}
+
+abstract class UnaryConstraint extends Constraint {
+ UnaryConstraint(this.myOutput, Strength strength) : super(strength) {}
+ Variable output() => myOutput;
+ bool inputsKnown(int mark) => true;
+ bool isSatisfied() => satisfied;
+ bool satisfied = false;
+ final Variable myOutput;
+ void addToGraph() {}
+ void chooseMethod(int mark) {}
+ void markInputs(int mark) {}
+ void markUnsatisfied() {}
+ void recalculate() {}
+ void removeFromGraph() {}
+}
+
+class DeltaBlue {
+ void run() {}
+}
+
+class EditConstraint extends UnaryConstraint {
+ EditConstraint(Variable v, Strength str) : super(v, str);
+ bool isInput() => true;
+ void execute() {}
+}
+
+class EqualityConstraint extends BinaryConstraint {
+ EqualityConstraint(Variable v1, Variable v2, Strength strength)
+ : super(v1, v2, strength);
+ void execute() {}
+}
+
+class Plan {
+ List<Constraint> list = <Constraint>[];
+ int size() => list.length;
+ void addConstraint(Constraint c) {}
+ void execute() {}
+}
+
+class Planner {
+ List<Constraint> removePropagateFrom(Variable out) {}
+ Plan extractPlanFromConstraints(List<Constraint> constraints) {}
+ Plan makePlan(List<Constraint> sources) {}
+ bool addPropagate(Constraint c, int mark) {}
+ int currentMark = 0;
+ int newMark() => ++currentMark;
+ void addConstraintsConsumingTo(Variable v, List<Constraint> coll) {}
+ void incrementalAdd(Constraint c) {}
+ void incrementalRemove(Constraint c) {}
+}
+
+class ScaleConstraint extends BinaryConstraint {
+ ScaleConstraint(
+ Variable src, this.scale, this.offset, Variable dest, Strength strength)
+ : super(src, dest, strength);
+ final Variable offset;
+ final Variable scale;
+ void addToGraph() {}
+ void execute() {}
+ void markInputs(int mark) {}
+ void recalculate() {}
+ void removeFromGraph() {}
+}
+
+class StayConstraint extends UnaryConstraint {
+ StayConstraint(Variable v, Strength str) : super(v, str);
+ void execute() {}
+}
+
+class Strength {
+ Strength nextWeaker() => const <Strength>[
+ STRONG_PREFERRED,
+ PREFERRED,
+ STRONG_DEFAULT,
+ NORMAL,
+ WEAK_DEFAULT,
+ WEAKEST
+ ][value];
+ const Strength(this.value, this.name);
+ final String name;
+ final int value;
+ static Strength strongest(Strength s1, Strength s2) {}
+ static Strength weakest(Strength s1, Strength s2) {}
+ static bool stronger(Strength s1, Strength s2) {}
+ static bool weaker(Strength s1, Strength s2) {}
+}
+
+class Variable {
+ Constraint determinedBy;
+ List<Constraint> constraints = <Constraint>[];
+ Strength walkStrength = WEAKEST;
+ Variable(this.name, this.value);
+ bool stay = true;
+ final String name;
+ int mark = 0;
+ int value;
+ void addConstraint(Constraint c) {}
+ void removeConstraint(Constraint c) {}
+}
+
+const NORMAL = const Strength(4, "normal");
+const PREFERRED = const Strength(2, "preferred");
+const REQUIRED = const Strength(0, "required");
+const STRONG_DEFAULT = const Strength(3, "strongDefault");
+const STRONG_PREFERRED = const Strength(1, "strongPreferred");
+const WEAKEST = const Strength(6, "weakest");
+const WEAK_DEFAULT = const Strength(5, "weakDefault");
+const int BACKWARD = 0;
+const int FORWARD = 2;
+const int NONE = 1;
+main() {}
+void chainTest(int n) {}
+void change(Variable v, int newValue) {}
+void projectionTest(int n) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/abstract_members.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/abstract_members.dart.textual_outline.expect
new file mode 100644
index 0000000..020c9cd
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/abstract_members.dart.textual_outline.expect
@@ -0,0 +1,81 @@
+// @dart = 2.6
+class Interface1 {
+ void interfaceMethod1() {}
+}
+
+class Interface2 {
+ void interfaceMethod2() {}
+ var interfaceMethod1;
+}
+
+class Interface3 {
+ void interfaceMethod3() {}
+}
+
+abstract class A implements Interface1, Interface2, Interface3 {
+ aMethod() {}
+ abstractMethod();
+ void set property1(_);
+ void set property2(_);
+ void set property3(_);
+}
+
+abstract class B extends A {
+ final property1 = null;
+ aMethod() {}
+ bMethod() {}
+}
+
+class MyClass extends B {
+ var property2;
+ aaMethod() {}
+ aMethod() {}
+ bMethod() {}
+ cMethod() {}
+}
+
+class MyMock1 extends B {
+ noSuchMethod(_) => null;
+}
+
+class MyMock2 extends MyMock1 {
+ noSuchMethod(_);
+}
+
+class MyMock3 extends B {
+ noSuchMethod(_);
+}
+
+class C {
+ void interfaceMethod1(_) {}
+}
+
+abstract class D extends C implements Interface2 {}
+
+class E {
+ void set interfaceMethod1(_) {}
+}
+
+abstract class F extends E implements Interface1 {}
+
+class Foo {
+ void foo() {}
+}
+
+class G {
+ Object get foo => null;
+}
+
+abstract class H extends G implements Foo {}
+
+class Bar {
+ Object get foo => null;
+}
+
+class I {
+ Object foo() {}
+}
+
+abstract class J extends I implements Bar {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/abstract_members.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/abstract_members.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6b5b578
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/abstract_members.dart.textual_outline_modelled.expect
@@ -0,0 +1,81 @@
+// @dart = 2.6
+abstract class A implements Interface1, Interface2, Interface3 {
+ aMethod() {}
+ abstractMethod();
+ void set property1(_);
+ void set property2(_);
+ void set property3(_);
+}
+
+abstract class B extends A {
+ aMethod() {}
+ bMethod() {}
+ final property1 = null;
+}
+
+abstract class D extends C implements Interface2 {}
+
+abstract class F extends E implements Interface1 {}
+
+abstract class H extends G implements Foo {}
+
+abstract class J extends I implements Bar {}
+
+class Bar {
+ Object get foo => null;
+}
+
+class C {
+ void interfaceMethod1(_) {}
+}
+
+class E {
+ void set interfaceMethod1(_) {}
+}
+
+class Foo {
+ void foo() {}
+}
+
+class G {
+ Object get foo => null;
+}
+
+class I {
+ Object foo() {}
+}
+
+class Interface1 {
+ void interfaceMethod1() {}
+}
+
+class Interface2 {
+ var interfaceMethod1;
+ void interfaceMethod2() {}
+}
+
+class Interface3 {
+ void interfaceMethod3() {}
+}
+
+class MyClass extends B {
+ aMethod() {}
+ aaMethod() {}
+ bMethod() {}
+ cMethod() {}
+ var property2;
+}
+
+class MyMock1 extends B {
+ noSuchMethod(_) => null;
+}
+
+class MyMock2 extends MyMock1 {
+ noSuchMethod(_);
+}
+
+class MyMock3 extends B {
+ noSuchMethod(_);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/abstract_overrides_concrete_with_no_such_method.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/abstract_overrides_concrete_with_no_such_method.dart.textual_outline.expect
new file mode 100644
index 0000000..51384b1
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/abstract_overrides_concrete_with_no_such_method.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+// @dart = 2.6
+abstract class A {
+ A foo() => null;
+}
+
+abstract class B extends A {
+ B foo();
+}
+
+class C {
+ noSuchMethod(_) => null;
+}
+
+class D extends C implements B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/abstract_overrides_concrete_with_no_such_method.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/abstract_overrides_concrete_with_no_such_method.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..51384b1
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/abstract_overrides_concrete_with_no_such_method.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+// @dart = 2.6
+abstract class A {
+ A foo() => null;
+}
+
+abstract class B extends A {
+ B foo();
+}
+
+class C {
+ noSuchMethod(_) => null;
+}
+
+class D extends C implements B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/accessors.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/accessors.dart.textual_outline.expect
new file mode 100644
index 0000000..1bfd600
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/accessors.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+// @dart = 2.6
+void set onlySetter(value) {}
+
+class C {
+ void set onlySetter(value) {}
+ testC() {}
+ testD() {}
+}
+
+class D extends C {
+ String get onlySetter => "D.onlySetter called.";
+ void set onlySetter(value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/accessors.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/accessors.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d39408e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/accessors.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+class C {
+ testC() {}
+ testD() {}
+ void set onlySetter(value) {}
+}
+
+class D extends C {
+ String get onlySetter => "D.onlySetter called.";
+ void set onlySetter(value) {}
+}
+
+main() {}
+void set onlySetter(value) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/all_variances.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/all_variances.dart.textual_outline.expect
new file mode 100644
index 0000000..858862a
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/all_variances.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+typedef F<W, X, Y, Z> = X Function(Y, Z Function(Z));
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/all_variances.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/all_variances.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8e98e2c
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/all_variances.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+main() {}
+typedef F<W, X, Y, Z> = X Function(Y, Z Function(Z));
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/ambiguous_exports.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/ambiguous_exports.dart.textual_outline.expect
new file mode 100644
index 0000000..1ee4fc3
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/ambiguous_exports.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+export 'hello.dart' show main;
+export 'map.dart' show main;
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/ambiguous_exports.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/ambiguous_exports.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1ee4fc3
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/ambiguous_exports.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+export 'hello.dart' show main;
+export 'map.dart' show main;
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/annotation_eof.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_eof.dart.textual_outline.expect
new file mode 100644
index 0000000..3e30daf
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_eof.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+main() { }
+@AnnotationAtEOF
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/annotation_on_enum_values.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_on_enum_values.dart.textual_outline.expect
new file mode 100644
index 0000000..3887a59
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_on_enum_values.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+// @dart = 2.6
+const int hest = 42;
+
+class Fisk<T> {
+ final T x;
+ const Fisk.fisk(this.x);
+}
+
+enum Foo {
+ @hest
+ bar,
+ @Fisk.fisk(hest)
+ baz,
+ cafebabe,
+}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/annotation_on_enum_values.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_on_enum_values.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..971520a
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_on_enum_values.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+// @dart = 2.6
+class Fisk<T> {
+ const Fisk.fisk(this.x);
+ final T x;
+}
+
+const int hest = 42;
+enum Foo {
+ @hest
+ bar,
+ @Fisk.fisk(hest)
+ baz,
+ cafebabe,
+}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/annotation_top.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_top.dart.textual_outline.expect
new file mode 100644
index 0000000..9309807
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_top.dart.textual_outline.expect
@@ -0,0 +1,27 @@
+// @dart = 2.6
+@a
+@A(1)
+library test;
+
+const Object a = const Object();
+
+class A {
+ const A(int value);
+}
+
+@a
+@A(2)
+class C {}
+
+@a
+@A(2)
+typedef void F1();
+@a
+@A(3)
+typedef F2 = void Function();
+@a
+@A(3)
+int f1, f2;
+@a
+@A(4)
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/annotation_top.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_top.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..093fb5b
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_top.dart.textual_outline_modelled.expect
@@ -0,0 +1,27 @@
+// @dart = 2.6
+@a
+@A(1)
+library test;
+
+@a
+@A(2)
+class C {}
+
+@a
+@A(2)
+typedef void F1();
+@a
+@A(3)
+int f1, f2;
+@a
+@A(3)
+typedef F2 = void Function();
+@a
+@A(4)
+void main() {}
+
+class A {
+ const A(int value);
+}
+
+const Object a = const Object();
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/annotation_typedef_formals.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_typedef_formals.dart.textual_outline.expect
new file mode 100644
index 0000000..615ace3
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_typedef_formals.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+const int foo = 21;
+const int bar = 42;
+const int baz = 84;
+typedef void F(@foo int x, num y, {@bar @baz String z, Object w});
+typedef void G(@foo int a, num b, [@bar @baz String c, Object d]);
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/annotation_typedef_formals.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_typedef_formals.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..837f56e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_typedef_formals.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+const int bar = 42;
+const int baz = 84;
+const int foo = 21;
+main() {}
+typedef void F(@foo int x, num y, {@bar @baz String z, Object w});
+typedef void G(@foo int a, num b, [@bar @baz String c, Object d]);
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/annotation_typedef_formals_resolution.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_typedef_formals_resolution.dart.textual_outline.expect
new file mode 100644
index 0000000..8f7e683
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_typedef_formals_resolution.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+const int app = 0;
+typedef int F(@app int app);
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/annotation_typedef_formals_resolution.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_typedef_formals_resolution.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..89c11f5
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_typedef_formals_resolution.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+const int app = 0;
+main() {}
+typedef int F(@app int app);
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/annotation_variable_declaration.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_variable_declaration.dart.textual_outline.expect
new file mode 100644
index 0000000..344db06
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_variable_declaration.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+// @dart = 2.6
+const int foo = 42;
+
+class Bar {
+ const Bar();
+ const Bar.named(x);
+}
+
+class Baz {
+ Baz(@foo constructorFormal);
+ factory Baz.bazFactory(@foo factoryFormal) => null;
+ fisk(@foo formal1, @Bar() formal2, @Bar.named(foo) formal3,
+ @foo @Bar.named(foo) formal4,
+ [@foo optional]) {}
+ hest({@foo named}) => null;
+}
+
+typedef hest_t({@foo named});
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/annotation_variable_declaration.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_variable_declaration.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..867b039
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/annotation_variable_declaration.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+// @dart = 2.6
+class Bar {
+ const Bar();
+ const Bar.named(x);
+}
+
+class Baz {
+ Baz(@foo constructorFormal);
+ factory Baz.bazFactory(@foo factoryFormal) => null;
+ fisk(@foo formal1, @Bar() formal2, @Bar.named(foo) formal3,
+ @foo @Bar.named(foo) formal4,
+ [@foo optional]) {}
+ hest({@foo named}) => null;
+}
+
+const int foo = 42;
+main() {}
+typedef hest_t({@foo named});
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/argument.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/argument.dart.textual_outline.expect
new file mode 100644
index 0000000..e20f5e7
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/argument.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+// @dart = 2.6
+abstract class Base {}
+
+class Foo extends Base {}
+
+class Bar extends Base {}
+
+class Baz extends Base {}
+
+void foo(x) {}
+void bar(x) {}
+void foo_escaped(x) {}
+void bar_escaped(x) {}
+void escape(fn) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/argument.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/argument.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4d47274
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/argument.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+// @dart = 2.6
+abstract class Base {}
+
+class Bar extends Base {}
+
+class Baz extends Base {}
+
+class Foo extends Base {}
+
+main() {}
+void bar(x) {}
+void bar_escaped(x) {}
+void escape(fn) {}
+void foo(x) {}
+void foo_escaped(x) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/argument_mismatch.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/argument_mismatch.dart.textual_outline.expect
new file mode 100644
index 0000000..efa46bf
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/argument_mismatch.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+foo() {}
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/argument_mismatch.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/argument_mismatch.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6201b42
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/argument_mismatch.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+foo() {}
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/arithmetic.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/arithmetic.dart.textual_outline.expect
new file mode 100644
index 0000000..ca67ea8
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/arithmetic.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+int foo(int x, int y) {}
+void loop(List xs) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/arithmetic.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/arithmetic.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c1ce4ed
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/arithmetic.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+int foo(int x, int y) {}
+main() {}
+void loop(List xs) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/arrow_function.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/arrow_function.dart.textual_outline.expect
new file mode 100644
index 0000000..75db4ee
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/arrow_function.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main<T>() => () => T;
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/arrow_function.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/arrow_function.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..75db4ee
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/arrow_function.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main<T>() => () => T;
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart.textual_outline.expect
new file mode 100644
index 0000000..68305dd
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+// @dart = 2.6
+import "package:expect/expect.dart";
+
+class A {
+ var x, y;
+ A(this.x)
+ : y = (() {
+ x = 3;
+ });
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b0144e8
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+// @dart = 2.6
+import "package:expect/expect.dart";
+
+class A {
+ A(this.x)
+ : y = (() {
+ x = 3;
+ });
+ var x, y;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/async_function.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/async_function.dart.textual_outline.expect
new file mode 100644
index 0000000..a305334
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/async_function.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+// @dart = 2.6
+import 'dart:async';
+
+Future<String> asyncString() async {}
+Future<String> asyncString2() async {}
+Iterable<String> syncStarString() sync* {}
+Iterable<String> syncStarString2() sync* {}
+Stream<String> asyncStarString() async* {}
+Stream<String> asyncStarString2() async* {}
+List<String> stringList = ["bar"];
+main() async {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/async_function.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/async_function.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4121d7b
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/async_function.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+// @dart = 2.6
+import 'dart:async';
+
+Future<String> asyncString() async {}
+Future<String> asyncString2() async {}
+Iterable<String> syncStarString() sync* {}
+Iterable<String> syncStarString2() sync* {}
+List<String> stringList = ["bar"];
+Stream<String> asyncStarString() async* {}
+Stream<String> asyncStarString2() async* {}
+main() async {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/async_nested.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/async_nested.dart.textual_outline.expect
new file mode 100644
index 0000000..9fc36c1
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/async_nested.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+// @dart = 2.6
+import 'dart:async';
+
+void main() async {}
+
+class Node {
+ final List<Node> nested;
+ final String name;
+ Node(this.name, [this.nested]) {}
+ String toString() => '<$name:[${nested?.join(', ')}]>';
+ toSimpleString() {}
+}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/async_nested.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/async_nested.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3092b93
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/async_nested.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+// @dart = 2.6
+import 'dart:async';
+
+class Node {
+ Node(this.name, [this.nested]) {}
+ String toString() => '<$name:[${nested?.join(', ')}]>';
+ final List<Node> nested;
+ final String name;
+ toSimpleString() {}
+}
+
+void main() async {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/await.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/await.dart.textual_outline.expect
new file mode 100644
index 0000000..f072043
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/await.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() async {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/await.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/await.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f072043
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/await.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() async {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/await_complex.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/await_complex.dart.textual_outline.expect
new file mode 100644
index 0000000..74baac0
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/await_complex.dart.textual_outline.expect
@@ -0,0 +1,41 @@
+// @dart = 2.6
+import 'dart:async';
+
+int globalVariable = 1;
+int topLevelFoo(int param) => 1;
+int get topLevelGetter => globalVariable;
+void set topLevelSetter(val) {}
+
+class C {
+ static int staticField = 1;
+ static int get staticGetter => staticField;
+ static void set staticSetter(val) {}
+ static int staticFoo(int param) => param;
+ int field = 1;
+ int get getter => field;
+ void set setter(val) {}
+ int foo(int param) => param;
+}
+
+dummy() => 1;
+staticMembers() async {}
+topLevelMembers() async {}
+instanceMembers() async {}
+others() async {}
+conditionals() async {}
+asserts() async {}
+controlFlow() async {}
+FutureOr<T> future<T>(T value) async => value;
+FutureOr<T> id<T>(T value) => value;
+Stream<int> intStream() async* {}
+final bool assertStatementsEnabled = () {
+ try {
+ assert(false);
+ return false;
+ } catch (_) {
+ return true;
+ }
+}();
+main() async {}
+expect(expected, actual) {}
+expectList(List expected, List actual) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/await_complex.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/await_complex.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cf5c4b2
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/await_complex.dart.textual_outline_modelled.expect
@@ -0,0 +1,41 @@
+// @dart = 2.6
+import 'dart:async';
+
+FutureOr<T> future<T>(T value) async => value;
+FutureOr<T> id<T>(T value) => value;
+Stream<int> intStream() async* {}
+asserts() async {}
+
+class C {
+ int field = 1;
+ int foo(int param) => param;
+ int get getter => field;
+ static int get staticGetter => staticField;
+ static int staticField = 1;
+ static int staticFoo(int param) => param;
+ static void set staticSetter(val) {}
+ void set setter(val) {}
+}
+
+conditionals() async {}
+controlFlow() async {}
+dummy() => 1;
+expect(expected, actual) {}
+expectList(List expected, List actual) {}
+final bool assertStatementsEnabled = () {
+ try {
+ assert(false);
+ return false;
+ } catch (_) {
+ return true;
+ }
+}();
+instanceMembers() async {}
+int get topLevelGetter => globalVariable;
+int globalVariable = 1;
+int topLevelFoo(int param) => 1;
+main() async {}
+others() async {}
+staticMembers() async {}
+topLevelMembers() async {}
+void set topLevelSetter(val) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/await_in_cascade.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/await_in_cascade.dart.textual_outline.expect
new file mode 100644
index 0000000..037786a
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/await_in_cascade.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+import 'dart:async';
+
+class C {
+ Future<List<int>> m() async => []..add(await _m());
+ Future<int> _m() async => 42;
+}
+
+main() async {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/await_in_cascade.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/await_in_cascade.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..19d43fa
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/await_in_cascade.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+import 'dart:async';
+
+class C {
+ Future<List<int>> m() async => []..add(await _m());
+ Future<int> _m() async => 42;
+}
+
+expect(expected, actual) {}
+main() async {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/await_in_non_async.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/await_in_non_async.dart.textual_outline.expect
new file mode 100644
index 0000000..3c7699f
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/await_in_non_async.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+main() {}
+foo() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/await_in_non_async.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/await_in_non_async.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..41dbdca
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/await_in_non_async.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bad_setter_abstract.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bad_setter_abstract.dart.textual_outline.expect
new file mode 100644
index 0000000..795c033
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bad_setter_abstract.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+// @dart = 2.6
+set b();
+set c(x, y);
+class A {
+ set a();
+ set d(x, y);
+}
+abstract class B {
+ set a();
+ set d(x, y);
+}
+main() { }
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bad_store.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bad_store.dart.textual_outline.expect
new file mode 100644
index 0000000..3955e86
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bad_store.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+class Foo {
+ var field;
+}
+
+dynamic identity(x) => x;
+void use(x) {}
+main(List<String> args) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bad_store.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bad_store.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b1bfa6a
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bad_store.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+class Foo {
+ var field;
+}
+
+dynamic identity(x) => x;
+main(List<String> args) {}
+void use(x) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bad_type_variable_uses_in_supertypes.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bad_type_variable_uses_in_supertypes.dart.textual_outline.expect
new file mode 100644
index 0000000..9fe865d
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bad_type_variable_uses_in_supertypes.dart.textual_outline.expect
@@ -0,0 +1,79 @@
+// @dart = 2.6
+typedef ContravariantUse<T> = Function(T);
+typedef InvariantUse<T> = T Function(T);
+
+class Empty {}
+
+class A<T> {}
+
+class B<T> extends A<Function(T)> {}
+
+class Bc<T> extends A<ContravariantUse<T>> {}
+
+class Bi<T> extends A<InvariantUse<T>> {}
+
+class C<T> implements A<Function(T)> {}
+
+class Cc<T> implements A<ContravariantUse<T>> {}
+
+class Ci<T> implements A<InvariantUse<T>> {}
+
+class D<T> = Object with A<Function(T)>;
+class Dc<T> = Object with A<ContravariantUse<T>>;
+class Di<T> = Object with A<InvariantUse<T>>;
+class E<T> = A<Function(T)> with Empty;
+class Ec<T> = A<ContravariantUse<T>> with Empty;
+class Ei<T> = A<InvariantUse<T>> with Empty;
+
+class F<T> extends Object with A<Function(T)> {}
+
+class Fc<T> extends Object with A<ContravariantUse<T>> {}
+
+class Fi<T> extends Object with A<InvariantUse<T>> {}
+
+class G<T> extends A<Function(T)> with Empty {}
+
+class Gc<T> extends A<ContravariantUse<T>> with Empty {}
+
+class Gi<T> extends A<InvariantUse<T>> with Empty {}
+
+class Hff<T> extends A<Function(Function(T))> {}
+
+class Hfc<T> extends A<Function(ContravariantUse<T>)> {}
+
+class Hcf<T> extends A<ContravariantUse<Function(T)>> {}
+
+class Hcc<T> extends A<ContravariantUse<ContravariantUse<T>>> {}
+
+class Hii<T> extends A<InvariantUse<InvariantUse<T>>> {}
+
+class Iafc<T> extends A<A<Function(ContravariantUse<T>)>> {}
+
+class Iacf<T> extends A<A<ContravariantUse<Function(T)>>> {}
+
+class Ifac<T> extends A<Function(A<ContravariantUse<T>>)> {}
+
+class Ifca<T> extends A<Function(ContravariantUse<A<T>>)> {}
+
+class Icaf<T> extends A<ContravariantUse<A<Function(T)>>> {}
+
+class Icfa<T> extends A<ContravariantUse<Function(A<T>)>> {}
+
+class Jfff<T> extends A<Function(Function(Function(T)))> {}
+
+class Jffc<T> extends A<Function(Function(ContravariantUse<T>))> {}
+
+class Jfcf<T> extends A<Function(ContravariantUse<Function(T)>)> {}
+
+class Jfcc<T> extends A<Function(ContravariantUse<ContravariantUse<T>>)> {}
+
+class Jcff<T> extends A<ContravariantUse<Function(Function(T))>> {}
+
+class Jcfc<T> extends A<ContravariantUse<Function(ContravariantUse<T>)>> {}
+
+class Jccf<T> extends A<ContravariantUse<ContravariantUse<Function(T)>>> {}
+
+class Jccc<T>
+ extends A<ContravariantUse<ContravariantUse<ContravariantUse<T>>>> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bad_type_variable_uses_in_supertypes.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bad_type_variable_uses_in_supertypes.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a1f06bf3
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bad_type_variable_uses_in_supertypes.dart.textual_outline_modelled.expect
@@ -0,0 +1,78 @@
+// @dart = 2.6
+class A<T> {}
+
+class B<T> extends A<Function(T)> {}
+
+class Bc<T> extends A<ContravariantUse<T>> {}
+
+class Bi<T> extends A<InvariantUse<T>> {}
+
+class C<T> implements A<Function(T)> {}
+
+class Cc<T> implements A<ContravariantUse<T>> {}
+
+class Ci<T> implements A<InvariantUse<T>> {}
+
+class Empty {}
+
+typedef ContravariantUse<T> = Function(T);
+typedef InvariantUse<T> = T Function(T);
+class D<T> = Object with A<Function(T)>;
+class Dc<T> = Object with A<ContravariantUse<T>>;
+class Di<T> = Object with A<InvariantUse<T>>;
+class E<T> = A<Function(T)> with Empty;
+class Ec<T> = A<ContravariantUse<T>> with Empty;
+class Ei<T> = A<InvariantUse<T>> with Empty;
+
+class F<T> extends Object with A<Function(T)> {}
+
+class Fc<T> extends Object with A<ContravariantUse<T>> {}
+
+class Fi<T> extends Object with A<InvariantUse<T>> {}
+
+class G<T> extends A<Function(T)> with Empty {}
+
+class Gc<T> extends A<ContravariantUse<T>> with Empty {}
+
+class Gi<T> extends A<InvariantUse<T>> with Empty {}
+
+class Hcc<T> extends A<ContravariantUse<ContravariantUse<T>>> {}
+
+class Hcf<T> extends A<ContravariantUse<Function(T)>> {}
+
+class Hfc<T> extends A<Function(ContravariantUse<T>)> {}
+
+class Hff<T> extends A<Function(Function(T))> {}
+
+class Hii<T> extends A<InvariantUse<InvariantUse<T>>> {}
+
+class Iacf<T> extends A<A<ContravariantUse<Function(T)>>> {}
+
+class Iafc<T> extends A<A<Function(ContravariantUse<T>)>> {}
+
+class Icaf<T> extends A<ContravariantUse<A<Function(T)>>> {}
+
+class Icfa<T> extends A<ContravariantUse<Function(A<T>)>> {}
+
+class Ifac<T> extends A<Function(A<ContravariantUse<T>>)> {}
+
+class Ifca<T> extends A<Function(ContravariantUse<A<T>>)> {}
+
+class Jccc<T>
+ extends A<ContravariantUse<ContravariantUse<ContravariantUse<T>>>> {}
+
+class Jccf<T> extends A<ContravariantUse<ContravariantUse<Function(T)>>> {}
+
+class Jcfc<T> extends A<ContravariantUse<Function(ContravariantUse<T>)>> {}
+
+class Jcff<T> extends A<ContravariantUse<Function(Function(T))>> {}
+
+class Jfcc<T> extends A<Function(ContravariantUse<ContravariantUse<T>>)> {}
+
+class Jfcf<T> extends A<Function(ContravariantUse<Function(T)>)> {}
+
+class Jffc<T> extends A<Function(Function(ContravariantUse<T>))> {}
+
+class Jfff<T> extends A<Function(Function(Function(T)))> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bounds_check_depends_on_inference.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bounds_check_depends_on_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..2cbc0b1
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bounds_check_depends_on_inference.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+// @dart = 2.6
+class A<X> {
+ bar<Y extends X>() => null;
+}
+
+class B {
+ static A<Y> foo<Y extends Object>() => null;
+}
+
+baz() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bounds_check_depends_on_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bounds_check_depends_on_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5f38302
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bounds_check_depends_on_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+// @dart = 2.6
+baz() {}
+
+class A<X> {
+ bar<Y extends X>() => null;
+}
+
+class B {
+ static A<Y> foo<Y extends Object>() => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug21938.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug21938.dart.textual_outline.expect
new file mode 100644
index 0000000..5cf5db8
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug21938.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug21938.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug21938.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..94295cd
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug21938.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug30695.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug30695.dart.textual_outline.expect
new file mode 100644
index 0000000..5a9e0bc
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug30695.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+class A {
+ var foo = 42;
+}
+
+class B extends A {
+ foo() => 42;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug30695.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug30695.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5a9e0bc
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug30695.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+class A {
+ var foo = 42;
+}
+
+class B extends A {
+ foo() => 42;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug31124.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug31124.dart.textual_outline.expect
new file mode 100644
index 0000000..fe4ea03
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug31124.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+var a = () => 'b';
+a();
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug32414a.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug32414a.dart.textual_outline.expect
new file mode 100644
index 0000000..c1995a0
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug32414a.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+void test() {}
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug32414a.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug32414a.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8f1f745
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug32414a.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+void main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug32414b.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug32414b.dart.textual_outline.expect
new file mode 100644
index 0000000..c1995a0
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug32414b.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+void test() {}
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug32414b.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug32414b.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8f1f745
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug32414b.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+void main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug32426.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug32426.dart.textual_outline.expect
new file mode 100644
index 0000000..df070ac
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug32426.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+abstract class I {
+ void call();
+}
+
+class C implements I {
+ void call([int x]) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug32426.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug32426.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..df070ac
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug32426.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+abstract class I {
+ void call();
+}
+
+class C implements I {
+ void call([int x]) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug32629.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug32629.dart.textual_outline.expect
new file mode 100644
index 0000000..06ad4f4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug32629.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+class A {
+ dynamic call(dynamic a, dynamic b) {}
+}
+
+typedef S Reducer<S>(S a, dynamic b);
+void foo<S>(Reducer<S> v) {}
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug32629.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug32629.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fc42c66
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug32629.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+class A {
+ dynamic call(dynamic a, dynamic b) {}
+}
+
+main() {}
+typedef S Reducer<S>(S a, dynamic b);
+void foo<S>(Reducer<S> v) {}
+void test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug32866.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug32866.dart.textual_outline.expect
new file mode 100644
index 0000000..233366a
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug32866.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+// @dart = 2.6
+abstract class B {
+ String get f;
+}
+
+class A implements B {
+ final f;
+ A(this.f);
+}
+
+var a = new A("foo");
+main() => print(a);
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug32866.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug32866.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..166e7e6
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug32866.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+// @dart = 2.6
+abstract class B {
+ String get f;
+}
+
+class A implements B {
+ A(this.f);
+ final f;
+}
+
+main() => print(a);
+var a = new A("foo");
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug33099.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug33099.dart.textual_outline.expect
new file mode 100644
index 0000000..004d115
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug33099.dart.textual_outline.expect
@@ -0,0 +1,23 @@
+// @dart = 2.6
+import 'dart:mirrors';
+
+const _FailingTest failingTest = const _FailingTest();
+
+class _FailingTest {
+ const _FailingTest();
+}
+
+class MyTest {
+ @failingTest
+ void foo() {}
+}
+
+class MyTest2 extends Object with MyTest {}
+
+main() {}
+bool _hasFailingTestAnnotation(MethodMirror method) {}
+bool _hasAnnotationInstance(DeclarationMirror declaration, instance) =>
+ declaration.metadata.any((InstanceMirror annotation) {
+ print('annotation: ${annotation.reflectee}');
+ return identical(annotation.reflectee, instance);
+ });
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug33099.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug33099.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..187b0dc
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug33099.dart.textual_outline_modelled.expect
@@ -0,0 +1,23 @@
+// @dart = 2.6
+import 'dart:mirrors';
+
+bool _hasAnnotationInstance(DeclarationMirror declaration, instance) =>
+ declaration.metadata.any((InstanceMirror annotation) {
+ print('annotation: ${annotation.reflectee}');
+ return identical(annotation.reflectee, instance);
+ });
+bool _hasFailingTestAnnotation(MethodMirror method) {}
+
+class MyTest {
+ @failingTest
+ void foo() {}
+}
+
+class MyTest2 extends Object with MyTest {}
+
+class _FailingTest {
+ const _FailingTest();
+}
+
+const _FailingTest failingTest = const _FailingTest();
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug33196.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug33196.dart.textual_outline.expect
new file mode 100644
index 0000000..8386cde
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug33196.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'dart:async';
+
+main() {}
+FutureOr<String> returnsString() async {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug33196.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug33196.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..71a68ef2
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug33196.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'dart:async';
+
+FutureOr<String> returnsString() async {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug33206.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug33206.dart.textual_outline.expect
new file mode 100644
index 0000000..2e821ff
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug33206.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+// @dart = 2.6
+import 'dart:async';
+
+class X {
+ final x;
+ final y;
+ X(this.x, this.y);
+ toString() => "X($x, $y)";
+}
+
+class Y {
+ f(_) {}
+}
+
+Future<List<Object>> f1() async {}
+List<Object> f2() => [2];
+Future<Object> f3() async {}
+Future<X> foo() async {}
+Future<void> main() async {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug33206.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug33206.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0fd457d
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug33206.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+// @dart = 2.6
+import 'dart:async';
+
+Future<List<Object>> f1() async {}
+Future<Object> f3() async {}
+Future<X> foo() async {}
+Future<void> main() async {}
+List<Object> f2() => [2];
+
+class X {
+ X(this.x, this.y);
+ final x;
+ final y;
+ toString() => "X($x, $y)";
+}
+
+class Y {
+ f(_) {}
+}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug33298.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug33298.dart.textual_outline.expect
new file mode 100644
index 0000000..f13a69c
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug33298.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+// @dart = 2.6
+class A {
+ String call(String s) => '$s$s';
+}
+
+class B<T> {
+ T call(T t) => t;
+}
+
+class C {
+ T call<T>(T t) => t;
+}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug33298.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug33298.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a95aef3
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug33298.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+// @dart = 2.6
+class A {
+ String call(String s) => '$s$s';
+}
+
+class B<T> {
+ T call(T t) => t;
+}
+
+class C {
+ T call<T>(T t) => t;
+}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug34511.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug34511.dart.textual_outline.expect
new file mode 100644
index 0000000..909ecab
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug34511.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+class A<X> {}
+
+class B<Z> extends Object with A<Z Function()> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug34511.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug34511.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..909ecab
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug34511.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+class A<X> {}
+
+class B<Z> extends Object with A<Z Function()> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug35470.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug35470.dart.textual_outline.expect
new file mode 100644
index 0000000..1b15757
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug35470.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+class A<X> {
+ foo<Y extends X>() {}
+}
+
+class B extends A<dynamic> {}
+
+bar(B b) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug35470.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug35470.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..72036e5
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug35470.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+bar(B b) {}
+
+class A<X> {
+ foo<Y extends X>() {}
+}
+
+class B extends A<dynamic> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug37476.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug37476.dart.textual_outline.expect
new file mode 100644
index 0000000..ba5130c
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug37476.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+// @dart = 2.6
+class A<T extends num> {
+ void Function<S extends T>(S x) foo() {}
+}
+
+class B<T extends num> {
+ void Function(T x) foo() {}
+}
+
+A<num> a = new A<int>();
+B<num> b = new B<int>();
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug37476.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug37476.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..14bd5a1
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug37476.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+// @dart = 2.6
+A<num> a = new A<int>();
+B<num> b = new B<int>();
+
+class A<T extends num> {
+ void Function<S extends T>(S x) foo() {}
+}
+
+class B<T extends num> {
+ void Function(T x) foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/call.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/call.dart.textual_outline.expect
new file mode 100644
index 0000000..1dcd347
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/call.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+class Callable {
+ call(x) {}
+}
+
+class CallableGetter {
+ get call => new Callable();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/call.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/call.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1dcd347
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/call.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+class Callable {
+ call(x) {}
+}
+
+class CallableGetter {
+ get call => new Callable();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/candidate_found.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/candidate_found.dart.textual_outline.expect
new file mode 100644
index 0000000..5dd8173
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/candidate_found.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+class Fisk {
+ Fisk(int x) {}
+ Fisk.named(int x) {}
+ void method(int x) {}
+ static void staticMethod(int x) {}
+}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/candidate_found.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/candidate_found.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3887387
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/candidate_found.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+class Fisk {
+ Fisk(int x) {}
+ Fisk.named(int x) {}
+ static void staticMethod(int x) {}
+ void method(int x) {}
+}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/cascade.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/cascade.dart.textual_outline.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/cascade.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/cascade.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/cascade.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/cascade.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/casts.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/casts.dart.textual_outline.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/casts.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/casts.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/casts.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/casts.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_allocation.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_allocation.dart.textual_outline.expect
new file mode 100644
index 0000000..e33a311
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_allocation.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_allocation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_allocation.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e33a311
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_allocation.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_as_check.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_as_check.dart.textual_outline.expect
new file mode 100644
index 0000000..f56ea38
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_as_check.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test(x) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_as_check.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_as_check.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f56ea38
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_as_check.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test(x) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_args.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_args.dart.textual_outline.expect
new file mode 100644
index 0000000..e2d52fb
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_args.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
+m2() => 1;
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_args.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_args.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..79e9487
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_args.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+m2() => 1;
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_args2.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_args2.dart.textual_outline.expect
new file mode 100644
index 0000000..d3c388c
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_args2.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() async {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_args2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_args2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d3c388c
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_args2.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() async {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_call.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_call.dart.textual_outline.expect
new file mode 100644
index 0000000..e33a311
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_call.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_call.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_call.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e33a311
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_call.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_write.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_write.dart.textual_outline.expect
new file mode 100644
index 0000000..e33a311
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_write.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_write.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_write.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e33a311
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_write.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_is_check.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_is_check.dart.textual_outline.expect
new file mode 100644
index 0000000..f56ea38
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_is_check.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test(x) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_is_check.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_is_check.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f56ea38
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_is_check.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test(x) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_read.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_read.dart.textual_outline.expect
new file mode 100644
index 0000000..e33a311
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_read.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_read.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_read.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e33a311
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_read.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_read_static_field.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_read_static_field.dart.textual_outline.expect
new file mode 100644
index 0000000..e33a311
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_read_static_field.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_read_static_field.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_read_static_field.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e33a311
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_read_static_field.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_read_type.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_read_type.dart.textual_outline.expect
new file mode 100644
index 0000000..e33a311
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_read_type.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_read_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_read_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e33a311
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_read_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_static_method_call.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_static_method_call.dart.textual_outline.expect
new file mode 100644
index 0000000..e33a311
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_static_method_call.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_static_method_call.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_static_method_call.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e33a311
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_static_method_call.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_type_declaration.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_type_declaration.dart.textual_outline.expect
new file mode 100644
index 0000000..b4c7b69
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_type_declaration.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() => test();
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_type_declaration.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_type_declaration.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b4c7b69
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_type_declaration.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as lib;
+
+main() => test();
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/circularity-via-initializing-formal.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/circularity-via-initializing-formal.dart.textual_outline.expect
new file mode 100644
index 0000000..8152764
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/circularity-via-initializing-formal.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+var x = new C._circular(null);
+
+class C {
+ var f = new C._circular(null);
+ C._circular(this.f);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/circularity-via-initializing-formal.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/circularity-via-initializing-formal.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e1a372d
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/circularity-via-initializing-formal.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+class C {
+ C._circular(this.f);
+ var f = new C._circular(null);
+}
+
+main() {}
+var x = new C._circular(null);
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/classes.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/classes.dart.textual_outline.expect
new file mode 100644
index 0000000..f95711e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/classes.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+class A {
+ final int x;
+ final int y;
+ A(this.y) : x = 42;
+ method() {}
+}
+
+class B extends A {
+ B(x) : super(x);
+ method() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/classes.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/classes.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9f02021
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/classes.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+class A {
+ A(this.y) : x = 42;
+ final int x;
+ final int y;
+ method() {}
+}
+
+class B extends A {
+ B(x) : super(x);
+ method() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/clone_function_type.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/clone_function_type.dart.textual_outline.expect
new file mode 100644
index 0000000..aaa6bd0
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/clone_function_type.dart.textual_outline.expect
@@ -0,0 +1,147 @@
+// @dart = 2.6
+class Am1<X, Y> {
+}
+class Bm1<Z> extends Object with Am1<Function(int), Z> {
+}
+class Cm1<Z> extends Object with Am1<Function(int x), Z> {
+}
+class Dm1<Z> extends Object with Am1<int Function(), Z> {
+}
+class Em1<Z> extends Object with Am1<Function(), Z> {
+}
+class Fm1<Z> extends Object with Am1<Function({int}), Z> {
+}
+class Gm1<Z> extends Object with Am1<Function({int x}), Z> {
+}
+class Hm1<Z> extends Object with Am1<Function([int]), Z> {
+}
+class Im1<Z> extends Object with Am1<Function([int x]), Z> {
+}
+class Jm1<Z> extends Object with Am1<Function, Z> {
+}
+class Km1<Z> extends Object with Am1<Function(Function Function), Z> {
+}
+class Lm1<Z> extends Object with Am1<Function(Function Function() Function) Function(), Z> {
+}
+class Mm1<Z> = Object with Am1<Function(int), Z>; class Nm1<Z> = Object with Am1<Function(int x), Z>; class Om1<Z> = Object with Am1<int Function(), Z>; class Pm1<Z> = Object with Am1<Function(), Z>; class Qm1<Z> = Object with Am1<Function({int}), Z>; class Rm1<Z> = Object with Am1<Function({int x}), Z>; class Sm1<Z> = Object with Am1<Function([int]), Z>; class Tm1<Z> = Object with Am1<Function([int x]), Z>; class Um1<Z> = Object with Am1<Function, Z>; class Vm1<Z> = Object with Am1<Function(Function Function), Z>; class Wm1<Z> = Object with Am1<Function(Function Function() Function) Function(), Z>;
+class Am2<X extends Function(), Y> {
+}
+class Bm2<Z> extends Object with Am2<Function(int), Z> {
+}
+class Cm2<Z> extends Object with Am2<Function(int x), Z> {
+}
+class Dm2<Z> extends Object with Am2<int Function(), Z> {
+}
+class Em2<Z> extends Object with Am2<Function(), Z> {
+}
+class Fm2<Z> extends Object with Am2<Function({int}), Z> {
+}
+class Gm2<Z> extends Object with Am2<Function({int x}), Z> {
+}
+class Hm2<Z> extends Object with Am2<Function([int]), Z> {
+}
+class Im2<Z> extends Object with Am2<Function([int x]), Z> {
+}
+class Jm2<Z> extends Object with Am2<Function, Z> {
+}
+class Km2<Z> extends Object with Am2<Function(Function Function), Z> {
+}
+class Lm2<Z> extends Object with Am2<Function(Function Function() Function) Function(), Z> {
+}
+class Mm2<Z> = Object with Am2<Function(int), Z>; class Nm2<Z> = Object with Am2<Function(int x), Z>; class Om2<Z> = Object with Am2<int Function(), Z>; class Pm2<Z> = Object with Am2<Function(), Z>; class Qm2<Z> = Object with Am2<Function({int}), Z>; class Rm2<Z> = Object with Am2<Function({int x}), Z>; class Sm2<Z> = Object with Am2<Function([int]), Z>; class Tm2<Z> = Object with Am2<Function([int x]), Z>; class Um2<Z> = Object with Am2<Function, Z>; class Vm2<Z> = Object with Am2<Function(Function Function), Z>; class Wm2<Z> = Object with Am2<Function(Function Function() Function) Function(), Z>;
+typedef TdB = Function(int);
+typedef TdC = Function(int x);
+typedef TdD = int Function();
+typedef TdE = Function();
+typedef TdF = Function({int});
+typedef TdG = Function({int x});
+typedef TdH = Function([int]);
+typedef TdI = Function([int x]);
+typedef TdJ = Function(Function Function);
+typedef TdK = Function(Function Function() Function) Function();
+class Am3<L, Y> {
+}
+class Bm3<Z> extends Object with Am3<TdB, Z> {
+}
+class Cm3<Z> extends Object with Am3<TdC, Z> {
+}
+class Dm3<Z> extends Object with Am3<TdD, Z> {
+}
+class Em3<Z> extends Object with Am3<TdE, Z> {
+}
+class Fm3<Z> extends Object with Am3<TdF, Z> {
+}
+class Gm3<Z> extends Object with Am3<TdG, Z> {
+}
+class Hm3<Z> extends Object with Am3<TdH, Z> {
+}
+class Im3<Z> extends Object with Am3<TdI, Z> {
+}
+class Jm3<Z> extends Object with Am3<TdJ, Z> {
+}
+class Km3<Z> extends Object with Am3<TdK, Z> {
+}
+class Af1<X extends Function(int)> {
+ factory Af1.foo() => null;
+}
+class Bf1<X extends Function(int x)> {
+ factory Bf1.foo() => null;
+}
+class Cf1<X extends int Function()> {
+ factory Cf1.foo() => null;
+}
+class Df1<X extends Function()> {
+ factory Df1.foo() => null;
+}
+class Ef1<X extends Function({int})> {
+ factory Ef1.foo() => null;
+}
+class Ff1<X extends Function({int x})> {
+ factory Ff1.foo() => null;
+}
+class Gf1<X extends Function([int])> {
+ factory Gf1.foo() => null;
+}
+class Hf1<X extends Function([int x])> {
+ factory Hf1.foo() => null;
+}
+class If1<X extends Function> {
+ factory If1.foo() => null;
+}
+class Jf1<X extends Function(Function Function)> {
+ factory Jf1.foo() => null;
+}
+class Kf1<X extends Function(Function Function() Function) Function()> {
+ factory Kf1.foo() => null;
+}
+class Bf2<X extends TdB> {
+ factory Bf2.foo() => null;
+}
+class Cf2<X extends TdC> {
+ factory Cf2.foo() => null;
+}
+class Df2<X extends TdD> {
+ factory Df2.foo() => null;
+}
+class Ef2<X extends TdE> {
+ factory Ef2.foo() => null;
+}
+class Ff2<X extends TdF> {
+ factory Ff2.foo() => null;
+}
+class Gf2<X extends TdG> {
+ factory Gf2.foo() => null;
+}
+class Hf2<X extends TdH> {
+ factory Hf2.foo() => null;
+}
+class If2<X extends TdI> {
+ factory If2.foo() => null;
+}
+class Jf2<X extends TdJ> {
+ factory Jf2.foo() => null;
+}
+class Kf2<X extends TdK> {
+ factory Kf2.foo() => null;
+}
+main() { }
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/closure.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/closure.dart.textual_outline.expect
new file mode 100644
index 0000000..6a14f58
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/closure.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+class Foo {
+ var _field = new Bar();
+}
+
+class Bar {}
+
+useCallback(callback) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/closure.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/closure.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f357b93
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/closure.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+class Bar {}
+
+class Foo {
+ var _field = new Bar();
+}
+
+main() {}
+useCallback(callback) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/co19_language_metadata_syntax_t04.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/co19_language_metadata_syntax_t04.dart.textual_outline.expect
new file mode 100644
index 0000000..14119f9
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/co19_language_metadata_syntax_t04.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+class A {
+ const A();
+}
+
+A() {}
+
+class B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/co19_language_metadata_syntax_t04.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/co19_language_metadata_syntax_t04.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e211177
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/co19_language_metadata_syntax_t04.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+A() {}
+
+class A {
+ const A();
+}
+
+class B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/complex_class_hierarchy.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/complex_class_hierarchy.dart.textual_outline.expect
new file mode 100644
index 0000000..a1e1341
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/complex_class_hierarchy.dart.textual_outline.expect
@@ -0,0 +1,44 @@
+// @dart = 2.6
+main() {}
+
+class A {}
+
+class B extends A {}
+
+class C extends B {}
+
+class D extends C {}
+
+class G<T extends A> {}
+
+class GB extends G<B> {}
+
+class GC extends G<C> {}
+
+class GD extends G<D> {}
+
+class X implements A {}
+
+class Y extends X {}
+
+class Z implements Y {}
+
+class W implements Z {}
+
+class GX implements G<A> {}
+
+class GY extends X implements GB {}
+
+class GZ implements Y, GC {}
+
+class GW implements Z, GD {}
+
+class GU extends GW {}
+
+class GV extends GU implements GW {}
+
+class ARO<S> {}
+
+class ARQ<T> extends Object implements ARO<T> {}
+
+class ARN extends ARQ<A> {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/complex_class_hierarchy.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/complex_class_hierarchy.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c7fa14d
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/complex_class_hierarchy.dart.textual_outline_modelled.expect
@@ -0,0 +1,44 @@
+// @dart = 2.6
+class A {}
+
+class ARN extends ARQ<A> {}
+
+class ARO<S> {}
+
+class ARQ<T> extends Object implements ARO<T> {}
+
+class B extends A {}
+
+class C extends B {}
+
+class D extends C {}
+
+class G<T extends A> {}
+
+class GB extends G<B> {}
+
+class GC extends G<C> {}
+
+class GD extends G<D> {}
+
+class GU extends GW {}
+
+class GV extends GU implements GW {}
+
+class GW implements Z, GD {}
+
+class GX implements G<A> {}
+
+class GY extends X implements GB {}
+
+class GZ implements Y, GC {}
+
+class W implements Z {}
+
+class X implements A {}
+
+class Y extends X {}
+
+class Z implements Y {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/compound_binary_implicit_as.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/compound_binary_implicit_as.dart.textual_outline.expect
new file mode 100644
index 0000000..5b66c35
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/compound_binary_implicit_as.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+class A {}
+
+class B extends A {
+ A operator +(B b) => new C();
+}
+
+class C extends A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/compound_binary_implicit_as.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/compound_binary_implicit_as.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5b66c35
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/compound_binary_implicit_as.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+class A {}
+
+class B extends A {
+ A operator +(B b) => new C();
+}
+
+class C extends A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/const_redirect_to_nonconst.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/const_redirect_to_nonconst.dart.textual_outline.expect
new file mode 100644
index 0000000..5e13631
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/const_redirect_to_nonconst.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+// @dart = 2.6
+class A {
+ const A() : this.bad();
+ A.bad() {}
+}
+
+class B extends A {
+ const B() : super.bad();
+}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/const_redirect_to_nonconst.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/const_redirect_to_nonconst.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0bfc5d3
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/const_redirect_to_nonconst.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+// @dart = 2.6
+class A {
+ A.bad() {}
+ const A() : this.bad();
+}
+
+class B extends A {
+ const B() : super.bad();
+}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/constructor_const_inference.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/constructor_const_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..dfe7905
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/constructor_const_inference.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+// @dart = 2.6
+class _Y<T> {
+ const _Y();
+}
+
+class A<T> {
+ _Y<T> x;
+ A(this.x);
+}
+
+class B<T> extends A<T> {
+ B() : super(const _Y());
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/constructor_const_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/constructor_const_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bd5e3b9
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/constructor_const_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+// @dart = 2.6
+class A<T> {
+ A(this.x);
+ _Y<T> x;
+}
+
+class B<T> extends A<T> {
+ B() : super(const _Y());
+}
+
+class _Y<T> {
+ const _Y();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/constructor_cycle.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/constructor_cycle.dart.textual_outline.expect
new file mode 100644
index 0000000..5bf13d8
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/constructor_cycle.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+class A {
+ A.foo() : this.bar();
+ A.bar() : this.foo();
+ A.baz() : this.foo();
+ A() : this();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/constructor_cycle.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/constructor_cycle.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4889e4e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/constructor_cycle.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+class A {
+ A() : this();
+ A.bar() : this.foo();
+ A.baz() : this.foo();
+ A.foo() : this.bar();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/constructor_function_types.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/constructor_function_types.dart.textual_outline.expect
new file mode 100644
index 0000000..6654976
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/constructor_function_types.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+// @dart = 2.6
+class A {
+ A();
+}
+
+class B {
+ B(int x, double y, String s);
+}
+
+class C<T> {
+ C();
+}
+
+class D<T, S> {
+ D(T x, S y);
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/constructor_function_types.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/constructor_function_types.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6654976
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/constructor_function_types.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+// @dart = 2.6
+class A {
+ A();
+}
+
+class B {
+ B(int x, double y, String s);
+}
+
+class C<T> {
+ C();
+}
+
+class D<T, S> {
+ D(T x, S y);
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/constructor_initializer_invalid.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/constructor_initializer_invalid.dart.textual_outline.expect
new file mode 100644
index 0000000..c29650c
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/constructor_initializer_invalid.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+class C1 {
+ int f;
+ C1() : =;
+}
+class C2 {
+ int f;
+ C2() : f=;
+}
+class C3 {
+ int f;
+ C3() : =f++;
+}
+main() { }
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/continue_inference_after_error.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/continue_inference_after_error.dart.textual_outline.expect
new file mode 100644
index 0000000..07cb3bd
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/continue_inference_after_error.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+import "continue_inference_after_error_lib.dart" as lib;
+
+class C {}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/continue_inference_after_error.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/continue_inference_after_error.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a5d615d
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/continue_inference_after_error.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+import "continue_inference_after_error_lib.dart" as lib;
+
+class C {}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection.dart.textual_outline.expect
new file mode 100644
index 0000000..7436629
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+main() {}
+oracle() => true;
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7436629
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+main() {}
+oracle() => true;
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..3974366
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.textual_outline.expect
@@ -0,0 +1,23 @@
+// @dart = 2.6
+oracle<T>([T t]) => true;
+testIfElement(dynamic dynVar, List<int> listInt, List<double> listDouble,
+ Map<String, int> mapToInt, Map<String, double> mapToDouble) {}
+testIfElementErrors(Map<int, int> map) {}
+testForElement(
+ dynamic dynVar,
+ List<int> listInt,
+ List<double> listDouble,
+ int index,
+ Map<String, int> mapStringInt,
+ Map<String, double> mapStringDouble) {}
+testForElementErrors(Map<int, int> map, List<int> list) async {}
+testForElementErrorsNotAsync(Stream<int> stream) {}
+
+class A {}
+
+class B extends A {
+ int get foo => 42;
+}
+
+testPromotion(A a) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1d03b2c
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,22 @@
+// @dart = 2.6
+class A {}
+
+class B extends A {
+ int get foo => 42;
+}
+
+main() {}
+oracle<T>([T t]) => true;
+testForElement(
+ dynamic dynVar,
+ List<int> listInt,
+ List<double> listDouble,
+ int index,
+ Map<String, int> mapStringInt,
+ Map<String, double> mapStringDouble) {}
+testForElementErrors(Map<int, int> map, List<int> list) async {}
+testForElementErrorsNotAsync(Stream<int> stream) {}
+testIfElement(dynamic dynVar, List<int> listInt, List<double> listDouble,
+ Map<String, int> mapToInt, Map<String, double> mapToDouble) {}
+testIfElementErrors(Map<int, int> map) {}
+testPromotion(A a) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart.textual_outline.expect
new file mode 100644
index 0000000..e4fba1e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+// @dart = 2.6
+class A {
+ bool operator ==(covariant A other) => true;
+}
+
+class B extends A {
+ bool operator ==(other) => true;
+}
+
+class C<T> {
+ bool operator ==(covariant C<T> other) => true;
+}
+
+class D extends C<int> {}
+
+main() {}
+test(A a, B b, C c_dynamic, C<int> c_int, C<String> c_string, D d) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e4fba1e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/covariant_equals.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+// @dart = 2.6
+class A {
+ bool operator ==(covariant A other) => true;
+}
+
+class B extends A {
+ bool operator ==(other) => true;
+}
+
+class C<T> {
+ bool operator ==(covariant C<T> other) => true;
+}
+
+class D extends C<int> {}
+
+main() {}
+test(A a, B b, C c_dynamic, C<int> c_int, C<String> c_string, D d) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/covariant_generic.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/covariant_generic.dart.textual_outline.expect
new file mode 100644
index 0000000..72ea40f
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/covariant_generic.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+// @dart = 2.6
+typedef void Callback<T>(T x);
+
+class Foo<T> {
+ final T finalField;
+ final Callback<T> callbackField;
+ T mutableField;
+ Callback<T> mutableCallbackField;
+ Foo(this.finalField, this.callbackField);
+ void method(T x) {}
+ set setter(T x) {}
+ void withCallback(Callback<T> callback) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/covariant_generic.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/covariant_generic.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..31c6cd5
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/covariant_generic.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+class Foo<T> {
+ Callback<T> mutableCallbackField;
+ Foo(this.finalField, this.callbackField);
+ T mutableField;
+ final Callback<T> callbackField;
+ final T finalField;
+ set setter(T x) {}
+ void method(T x) {}
+ void withCallback(Callback<T> callback) {}
+}
+
+main() {}
+typedef void Callback<T>(T x);
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/covariant_parameter_in_superclass_of_mixin_application.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/covariant_parameter_in_superclass_of_mixin_application.dart.textual_outline.expect
new file mode 100644
index 0000000..9bbf948
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/covariant_parameter_in_superclass_of_mixin_application.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+// @dart = 2.6
+class A {
+ void foo(covariant num x) {}
+}
+
+class B {
+ void foo(num x) {}
+}
+
+class C {
+ void foo(num x) {}
+}
+
+class D extends A with B implements C {
+ void foo(int x) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/covariant_parameter_in_superclass_of_mixin_application.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/covariant_parameter_in_superclass_of_mixin_application.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9bbf948
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/covariant_parameter_in_superclass_of_mixin_application.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+// @dart = 2.6
+class A {
+ void foo(covariant num x) {}
+}
+
+class B {
+ void foo(num x) {}
+}
+
+class C {
+ void foo(num x) {}
+}
+
+class D extends A with B implements C {
+ void foo(int x) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/cycles.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/cycles.dart.textual_outline.expect
new file mode 100644
index 0000000..63a5f33
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/cycles.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+class A implements C {}
+
+class B extends A {}
+
+class C extends B implements D {}
+
+class D {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/cycles.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/cycles.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..63a5f33
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/cycles.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+class A implements C {}
+
+class B extends A {}
+
+class C extends B implements D {}
+
+class D {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/default_values.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/default_values.dart.textual_outline.expect
new file mode 100644
index 0000000..d390870
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/default_values.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+topLevel([a = 42]) => a;
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/default_values.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/default_values.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ddce93f
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/default_values.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+main() {}
+topLevel([a = 42]) => a;
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/deferred_type_annotation.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/deferred_type_annotation.dart.textual_outline.expect
new file mode 100644
index 0000000..5b64564
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/deferred_type_annotation.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as d;
+
+bad(d.C x) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/deferred_type_annotation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/deferred_type_annotation.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5b64564
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/deferred_type_annotation.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'deferred_lib.dart' deferred as d;
+
+bad(d.C x) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_bad_prefix.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_bad_prefix.dart.textual_outline.expect
new file mode 100644
index 0000000..2c4038e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_bad_prefix.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+import 'duplicated_bad_prefix_lib1.dart' as dupe;
+import 'duplicated_bad_prefix_lib2.dart' as dupe;
+
+class Dupe {}
+
+class Dupe {}
+
+class C {
+ Dupe.a b;
+ dupe.C d;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_bad_prefix.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_bad_prefix.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f7b1746
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_bad_prefix.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+import 'duplicated_bad_prefix_lib1.dart' as dupe;
+import 'duplicated_bad_prefix_lib2.dart' as dupe;
+
+class C {
+ Dupe.a b;
+ dupe.C d;
+}
+
+class Dupe {}
+
+class Dupe {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_declarations.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_declarations.dart.textual_outline.expect
new file mode 100644
index 0000000..f7ac94b
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_declarations.dart.textual_outline.expect
@@ -0,0 +1,34 @@
+// @dart = 2.6
+part "duplicated_declarations_part.dart"; import 'duplicated_declarations_lib.dart' as Typedef; import 'duplicated_declarations_lib.dart' as Typedef;
+typedef Typedef = void Function();
+typedef Typedef = Object Function();
+import 'duplicated_declarations_lib.dart' as Typedef;
+typedef void OldTypedef();
+typedef Object OldTypedef();
+var field = "1st";
+var field = "2nd";
+main() { }
+main() { }
+foo() { }
+class C {
+ C(a);
+ C(a, b);
+ var field = "1st";
+ var field = "2nd";
+ m() { }
+ m() { }
+ static s() { }
+ static s() { }
+ static f() => s;
+}
+class Sub extends C {
+ Sub() : super(null);
+ m() => super.m();
+}
+class C {
+ C._();
+}
+enum Enum { Enum, a, a, b, }
+enum Enum { a, b, c, }
+enum AnotherEnum { a, b, c, _name, index, toString, values, }
+useAnotherEnum() { }
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_field_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_field_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..9d71884
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_field_initializer.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+class A {
+ int a;
+ int a;
+ A(this.a);
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_field_initializer.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_field_initializer.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..82dc367
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_field_initializer.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+class A {
+ A(this.a);
+ int a;
+ int a;
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_named_args_3.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_named_args_3.dart.textual_outline.expect
new file mode 100644
index 0000000..a8791fb
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_named_args_3.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+library test;
+
+class C {
+ static m({int a: 0}) {}
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_named_args_3.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_named_args_3.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7d76a64
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_named_args_3.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+library test;
+
+class C {
+ static m({int a: 0}) {}
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/dynamic_and_void.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/dynamic_and_void.dart.textual_outline.expect
new file mode 100644
index 0000000..32b4171
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/dynamic_and_void.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'dart:core' show int;
+
+dynamic testDynamic() => 0;
+void testVoid() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/dynamic_and_void.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/dynamic_and_void.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e08ab2d
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/dynamic_and_void.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'dart:core' show int;
+
+dynamic testDynamic() => 0;
+main() {}
+void testVoid() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_01.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_01.dart.textual_outline.expect
new file mode 100644
index 0000000..c7f2b39
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_01.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'error_location_01_lib1.dart';
+import 'error_location_01_lib2.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_01.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_01.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c7f2b39
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_01.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'error_location_01_lib1.dart';
+import 'error_location_01_lib2.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_02.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_02.dart.textual_outline.expect
new file mode 100644
index 0000000..4a65ff5
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_02.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'error_location_02_lib1.dart';
+import 'error_location_02_lib2.dart';
+import 'error_location_02_lib3.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_02.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_02.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4a65ff5
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_02.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'error_location_02_lib1.dart';
+import 'error_location_02_lib2.dart';
+import 'error_location_02_lib3.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_03.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_03.dart.textual_outline.expect
new file mode 100644
index 0000000..028a793
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_03.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'error_location_03_lib1.dart';
+import 'error_location_03_lib2.dart';
+import 'error_location_03_lib3.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_03.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_03.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..028a793
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_03.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'error_location_03_lib1.dart';
+import 'error_location_03_lib2.dart';
+import 'error_location_03_lib3.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_04.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_04.dart.textual_outline.expect
new file mode 100644
index 0000000..3deded7
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_04.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'error_location_04_lib1.dart';
+import 'error_location_04_lib2.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_04.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_04.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3deded7
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_04.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'error_location_04_lib1.dart';
+import 'error_location_04_lib2.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_05.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_05.dart.textual_outline.expect
new file mode 100644
index 0000000..e2be00e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_05.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+library error_location_05;
+
+part 'error_location_05_lib1.dart';
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_05.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_05.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e2be00e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_05.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+library error_location_05;
+
+part 'error_location_05_lib1.dart';
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_06.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_06.dart.textual_outline.expect
new file mode 100644
index 0000000..218450a
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_06.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+library error_location_06;
+
+part 'error_location_06_lib1.dart';
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_06.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_06.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..218450a
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/error_locations/error_location_06.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+library error_location_06;
+
+part 'error_location_06_lib1.dart';
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/escape.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/escape.dart.textual_outline.expect
new file mode 100644
index 0000000..bdc547b
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/escape.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+// @dart = 2.6
+class A {
+ var field;
+}
+
+class B {
+ var field;
+}
+
+class C {
+ operator ==(x) => false;
+}
+
+class X implements A, B {
+ var field;
+}
+
+void useAsA(A object) {}
+void useAsB(B object) {}
+void escape(x) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/escape.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/escape.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..344fffd
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/escape.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+// @dart = 2.6
+class A {
+ var field;
+}
+
+class B {
+ var field;
+}
+
+class C {
+ operator ==(x) => false;
+}
+
+class X implements A, B {
+ var field;
+}
+
+main() {}
+void escape(x) {}
+void useAsA(A object) {}
+void useAsB(B object) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/export_main.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/export_main.dart.textual_outline.expect
new file mode 100644
index 0000000..711d1b4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/export_main.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+export 'hello.dart' show main;
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/export_main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/export_main.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..711d1b4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/export_main.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+export 'hello.dart' show main;
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/export_test.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/export_test.dart.textual_outline.expect
new file mode 100644
index 0000000..8188bed
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/export_test.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'dart:developer' show UserTag;
+export 'dart:core' show print;
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/export_test.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/export_test.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8188bed
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/export_test.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import 'dart:developer' show UserTag;
+export 'dart:core' show print;
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/expressions.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/expressions.dart.textual_outline.expect
new file mode 100644
index 0000000..1b5dea8
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/expressions.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+foo({fisk}) {}
+caller(f) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/expressions.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/expressions.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2426a32
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/expressions.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+caller(f) {}
+foo({fisk}) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/extend_with_type_variable.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/extend_with_type_variable.dart.textual_outline.expect
new file mode 100644
index 0000000..4fb5044
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/extend_with_type_variable.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+class SuperClass {}
+
+mixin Mixin<T> {}
+
+class Class1<T, S extends SuperClass> extends S with Mixin<T> {}
+
+class Class2<T, M extends Mixin<T>> extends SuperClass with M {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/extend_with_type_variable.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/extend_with_type_variable.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7d6e04d
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/extend_with_type_variable.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+class Class1<T, S extends SuperClass> extends S with Mixin<T> {}
+
+class Class2<T, M extends Mixin<T>> extends SuperClass with M {}
+
+class SuperClass {}
+
+main() {}
+mixin Mixin<T> {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/external.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/external.dart.textual_outline.expect
new file mode 100644
index 0000000..72d8f00
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/external.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'dart:isolate';
+
+var subscription;
+void onData(x) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/external.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/external.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..de46c08
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/external.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'dart:isolate';
+
+main() {}
+var subscription;
+void onData(x) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/external_import.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/external_import.dart.textual_outline.expect
new file mode 100644
index 0000000..e1f051e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/external_import.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'dart-ext:here';
+import 'dart-ext:foo/../there';
+import 'dart-ext:/usr/local/somewhere';
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/external_import.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/external_import.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e1f051e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/external_import.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import 'dart-ext:here';
+import 'dart-ext:foo/../there';
+import 'dart-ext:/usr/local/somewhere';
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/fallthrough.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/fallthrough.dart.textual_outline.expect
new file mode 100644
index 0000000..9b82bc0
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/fallthrough.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+void main(List<String> args) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/fallthrough.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/fallthrough.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9b82bc0
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/fallthrough.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+void main(List<String> args) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.textual_outline.expect
new file mode 100644
index 0000000..e4af729
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+import 'dart:ffi';
+import "package:ffi/ffi.dart";
+
+class Coordinate extends Struct {
+ @Double()
+ double x;
+ @Double()
+ double y;
+ Pointer<Coordinate> next;
+ factory Coordinate.allocate(double x, double y, Pointer<Coordinate> next) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e4af729
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/ffi_sample.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+import 'dart:ffi';
+import "package:ffi/ffi.dart";
+
+class Coordinate extends Struct {
+ @Double()
+ double x;
+ @Double()
+ double y;
+ Pointer<Coordinate> next;
+ factory Coordinate.allocate(double x, double y, Pointer<Coordinate> next) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/fibonacci.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/fibonacci.dart.textual_outline.expect
new file mode 100644
index 0000000..5e1c191
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/fibonacci.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+int fibonacci(int n) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/fibonacci.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/fibonacci.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5e1c191
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/fibonacci.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+int fibonacci(int n) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/for_in_scope.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/for_in_scope.dart.textual_outline.expect
new file mode 100644
index 0000000..b6ad80a
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/for_in_scope.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main(List<String> arguments) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/for_in_scope.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/for_in_scope.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b6ad80a
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/for_in_scope.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main(List<String> arguments) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart.textual_outline.expect
new file mode 100644
index 0000000..9808898
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+// @dart = 2.6
+bool topLevelField;
+var untypedTopLevelField;
+
+class Super {
+ int superInstanceField;
+ var untypedSuperInstanceField;
+}
+
+class C extends Super {
+ int instanceField;
+ var untypedInstanceField;
+ static double staticField;
+ static var untypedStaticField;
+ m() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5b2d0b2
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+// @dart = 2.6
+bool topLevelField;
+
+class C extends Super {
+ int instanceField;
+ m() {}
+ static double staticField;
+ static var untypedStaticField;
+ var untypedInstanceField;
+}
+
+class Super {
+ int superInstanceField;
+ var untypedSuperInstanceField;
+}
+
+main() {}
+var untypedTopLevelField;
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/forwarding_stub_for_operator.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/forwarding_stub_for_operator.dart.textual_outline.expect
new file mode 100644
index 0000000..797b2be
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/forwarding_stub_for_operator.dart.textual_outline.expect
@@ -0,0 +1,20 @@
+// @dart = 2.6
+class A {
+ dynamic operator +(covariant int a) => null;
+}
+
+class B {
+ dynamic operator +(dynamic b) => null;
+}
+
+abstract class C implements A, B {}
+
+class D {
+ dynamic operator +(dynamic d) => null;
+}
+
+class E extends D {
+ dynamic operator +(covariant int e);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/forwarding_stub_for_operator.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/forwarding_stub_for_operator.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6d028dc
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/forwarding_stub_for_operator.dart.textual_outline_modelled.expect
@@ -0,0 +1,20 @@
+// @dart = 2.6
+abstract class C implements A, B {}
+
+class A {
+ dynamic operator +(covariant int a) => null;
+}
+
+class B {
+ dynamic operator +(dynamic b) => null;
+}
+
+class D {
+ dynamic operator +(dynamic d) => null;
+}
+
+class E extends D {
+ dynamic operator +(covariant int e);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/function_in_field.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/function_in_field.dart.textual_outline.expect
new file mode 100644
index 0000000..cf6cafe
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/function_in_field.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+var x = () {
+ var y = 42;
+ return y;
+};
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/function_in_field.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/function_in_field.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..186e9b4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/function_in_field.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+main() {}
+var x = () {
+ var y = 42;
+ return y;
+};
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/function_type_assignments.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/function_type_assignments.dart.textual_outline.expect
new file mode 100644
index 0000000..008e4b9
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/function_type_assignments.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+T identity<T>(T t) => t;
+T identityObject<T extends Object>(T t) => t;
+T identityList<T extends List<T>>(T t) => t;
+String x = identity;
+String y = identityObject;
+String z = identityList;
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/function_type_assignments.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/function_type_assignments.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b27eac3
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/function_type_assignments.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+String x = identity;
+String y = identityObject;
+String z = identityList;
+T identity<T>(T t) => t;
+T identityList<T extends List<T>>(T t) => t;
+T identityObject<T extends Object>(T t) => t;
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/function_type_default_value.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/function_type_default_value.dart.textual_outline.expect
new file mode 100644
index 0000000..6650610
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/function_type_default_value.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+void Function({obj: Object}) x;
+main() { }
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/function_type_is_check.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/function_type_is_check.dart.textual_outline.expect
new file mode 100644
index 0000000..eade016
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/function_type_is_check.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import "package:expect/expect.dart" show Expect;
+
+test(f) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/function_type_is_check.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/function_type_is_check.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..207b09a
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/function_type_is_check.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import "package:expect/expect.dart" show Expect;
+
+main() {}
+test(f) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/function_type_recovery.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/function_type_recovery.dart.textual_outline.expect
new file mode 100644
index 0000000..569b9be
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/function_type_recovery.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+typedef F = int Function(int f(String x));
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/function_type_recovery.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/function_type_recovery.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..95953c9
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/function_type_recovery.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+main() {}
+typedef F = int Function(int f(String x));
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/functions.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/functions.dart.textual_outline.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/functions.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/functions.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/functions.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/functions.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/future_or_test.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/future_or_test.dart.textual_outline.expect
new file mode 100644
index 0000000..7123fde
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/future_or_test.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+// @dart = 2.6
+import 'dart:async';
+
+class A {
+ dynamic foo() => null;
+}
+
+class B {
+ A a;
+ Future<dynamic> bar() async => a.foo();
+}
+
+class C {
+ B b = B();
+ Future<int> baz() async => b.bar();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/future_or_test.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/future_or_test.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7123fde
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/future_or_test.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+// @dart = 2.6
+import 'dart:async';
+
+class A {
+ dynamic foo() => null;
+}
+
+class B {
+ A a;
+ Future<dynamic> bar() async => a.foo();
+}
+
+class C {
+ B b = B();
+ Future<int> baz() async => b.bar();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/generic_function_type_in_message.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/generic_function_type_in_message.dart.textual_outline.expect
new file mode 100644
index 0000000..c120177
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/generic_function_type_in_message.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+num add<A extends num, B extends num>(A a, B b) => a + b;
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/generic_function_type_in_message.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/generic_function_type_in_message.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a09c841
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/generic_function_type_in_message.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+main() {}
+num add<A extends num, B extends num>(A a, B b) => a + b;
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/having_part_with_part_and_annotation.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/having_part_with_part_and_annotation.dart.textual_outline.expect
new file mode 100644
index 0000000..2e43bfb
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/having_part_with_part_and_annotation.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+@Foo
+part 'having_part_with_part_and_annotation_lib1.dart';
+
+const int Foo = 42;
+void fromMain() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/having_part_with_part_and_annotation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/having_part_with_part_and_annotation.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c66d6f8
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/having_part_with_part_and_annotation.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+@Foo
+part 'having_part_with_part_and_annotation_lib1.dart';
+
+const int Foo = 42;
+main() {}
+void fromMain() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/having_part_with_parts_and_annotation.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/having_part_with_parts_and_annotation.dart.textual_outline.expect
new file mode 100644
index 0000000..48738fd
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/having_part_with_parts_and_annotation.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+@Foo
+part 'having_part_with_parts_and_annotation_lib1.dart';
+
+const int Foo = 42;
+void fromMain() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/having_part_with_parts_and_annotation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/having_part_with_parts_and_annotation.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..485fed8
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/having_part_with_parts_and_annotation.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+@Foo
+part 'having_part_with_parts_and_annotation_lib1.dart';
+
+const int Foo = 42;
+main() {}
+void fromMain() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/hello.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/hello.dart.textual_outline.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/hello.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/hello.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/hello.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/hello.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_cascade.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_cascade.dart.textual_outline.expect
new file mode 100644
index 0000000..d00fcfd
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_cascade.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+class Class {
+ method() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_cascade.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_cascade.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d00fcfd
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_cascade.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+class Class {
+ method() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_list_literal.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_list_literal.dart.textual_outline.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_list_literal.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_list_literal.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_list_literal.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_list_literal.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_set_literal.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_set_literal.dart.textual_outline.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_set_literal.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_set_literal.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_set_literal.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/if_null_in_set_literal.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/ignore_function.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/ignore_function.dart.textual_outline.expect
new file mode 100644
index 0000000..d0ad2e6
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/ignore_function.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+// @dart = 2.6
+import "dart:core" as core;
+
+class A implements core.Function {
+ operator ==(other) => false;
+}
+
+class B implements Function {
+ operator ==(other) => false;
+}
+
+class Function {
+ core.bool operator ==(core.Object other) => false;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/ignore_function.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/ignore_function.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0ad2e6
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/ignore_function.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+// @dart = 2.6
+import "dart:core" as core;
+
+class A implements core.Function {
+ operator ==(other) => false;
+}
+
+class B implements Function {
+ operator ==(other) => false;
+}
+
+class Function {
+ core.bool operator ==(core.Object other) => false;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/illegal_named_function_expression.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/illegal_named_function_expression.dart.textual_outline.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/illegal_named_function_expression.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/illegal_named_function_expression.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/illegal_named_function_expression.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/illegal_named_function_expression.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/illegal_named_function_expression_scope.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/illegal_named_function_expression_scope.dart.textual_outline.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/illegal_named_function_expression_scope.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/illegal_named_function_expression_scope.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/illegal_named_function_expression_scope.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/illegal_named_function_expression_scope.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/implicit_const_with_static_fields.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/implicit_const_with_static_fields.dart.textual_outline.expect
new file mode 100644
index 0000000..c31ef38
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/implicit_const_with_static_fields.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+const constTopLevelField = 42;
+
+class C {
+ const C(x);
+ static const constField = 87;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/implicit_const_with_static_fields.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/implicit_const_with_static_fields.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8a51783
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/implicit_const_with_static_fields.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+class C {
+ const C(x);
+ static const constField = 87;
+}
+
+const constTopLevelField = 42;
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/implicit_new.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/implicit_new.dart.textual_outline.expect
new file mode 100644
index 0000000..7b7c2fb
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/implicit_new.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+// @dart = 2.6
+import "implicit_new.dart" as prefix;
+
+class Foo {
+ operator +(other) => null;
+}
+
+class Bar {
+ Bar.named();
+ operator +(other) => null;
+}
+
+testNSM() {}
+f(x) => x;
+
+class IndexTester {
+ operator [](_) => null;
+ void operator []=(_a, _b) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/implicit_new.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/implicit_new.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d1ae95e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/implicit_new.dart.textual_outline_modelled.expect
@@ -0,0 +1,20 @@
+// @dart = 2.6
+import "implicit_new.dart" as prefix;
+
+class Bar {
+ Bar.named();
+ operator +(other) => null;
+}
+
+class Foo {
+ operator +(other) => null;
+}
+
+class IndexTester {
+ operator [](_) => null;
+ void operator []=(_a, _b) {}
+}
+
+f(x) => x;
+main() {}
+testNSM() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/implicit_scope_test.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/implicit_scope_test.dart.textual_outline.expect
new file mode 100644
index 0000000..ea15953
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/implicit_scope_test.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+import "package:expect/expect.dart";
+
+class ImplicitScopeTest {
+ static bool alwaysTrue() {}
+ static testMain() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/implicit_scope_test.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/implicit_scope_test.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ea15953
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/implicit_scope_test.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+import "package:expect/expect.dart";
+
+class ImplicitScopeTest {
+ static bool alwaysTrue() {}
+ static testMain() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/implicit_this.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/implicit_this.dart.textual_outline.expect
new file mode 100644
index 0000000..7971f11
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/implicit_this.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+// @dart = 2.6
+class C {
+ m() {}
+ testC() {}
+}
+
+class D extends C {
+ testD() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/implicit_this.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/implicit_this.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7971f11
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/implicit_this.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+// @dart = 2.6
+class C {
+ m() {}
+ testC() {}
+}
+
+class D extends C {
+ testD() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_getters.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_getters.dart.textual_outline.expect
new file mode 100644
index 0000000..a245e33
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_getters.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'import_conflicting_getters_lib1.dart';
+import 'import_conflicting_getters_lib2.dart';
+
+main() {}
+errors() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_getters.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_getters.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6d91e80
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_getters.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'import_conflicting_getters_lib1.dart';
+import 'import_conflicting_getters_lib2.dart';
+
+errors() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_setters.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_setters.dart.textual_outline.expect
new file mode 100644
index 0000000..ac0d854
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_setters.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'import_conflicting_setters_lib1.dart';
+import 'import_conflicting_setters_lib2.dart';
+
+main() {}
+errors() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_setters.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_setters.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..592f7b0
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_setters.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'import_conflicting_setters_lib1.dart';
+import 'import_conflicting_setters_lib2.dart';
+
+errors() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_type_member.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_type_member.dart.textual_outline.expect
new file mode 100644
index 0000000..79e6e92
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_type_member.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'import_conflicting_type_member_lib1.dart';
+import 'import_conflicting_type_member_lib2.dart';
+
+main() {}
+errors() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_type_member.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_type_member.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..71e6b48
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_type_member.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'import_conflicting_type_member_lib1.dart';
+import 'import_conflicting_type_member_lib2.dart';
+
+errors() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_types.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_types.dart.textual_outline.expect
new file mode 100644
index 0000000..287c61f
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_types.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'import_conflicting_types_lib1.dart';
+import 'import_conflicting_types_lib2.dart';
+
+main() {}
+errors() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_types.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_types.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..48302b2
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/import_conflicting_types.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'import_conflicting_types_lib1.dart';
+import 'import_conflicting_types_lib2.dart';
+
+errors() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/incomplete_field_formal_parameter.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/incomplete_field_formal_parameter.dart.textual_outline.expect
new file mode 100644
index 0000000..23e89ac
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/incomplete_field_formal_parameter.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+class C {
+ C.a(this.);
+ C.b(this.);
+ C.c(this., p);
+ C.d(this., p);
+}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/interface_contravariant_from_class.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/interface_contravariant_from_class.dart.textual_outline.expect
new file mode 100644
index 0000000..121eb31
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/interface_contravariant_from_class.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+// @dart = 2.6
+library test;
+
+typedef void F<T>(T t);
+
+class B<T> {
+ T f(int x) {}
+}
+
+abstract class I<T> {
+ T f(Object x);
+}
+
+abstract class C<T> extends B<F<T>> implements I<F<T>> {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/interface_contravariant_from_class.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/interface_contravariant_from_class.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2c05413
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/interface_contravariant_from_class.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+// @dart = 2.6
+library test;
+
+abstract class C<T> extends B<F<T>> implements I<F<T>> {}
+
+abstract class I<T> {
+ T f(Object x);
+}
+
+class B<T> {
+ T f(int x) {}
+}
+
+typedef void F<T>(T t);
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/interface_covariantImpl_from_class.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/interface_covariantImpl_from_class.dart.textual_outline.expect
new file mode 100644
index 0000000..5525e8f
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/interface_covariantImpl_from_class.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+// @dart = 2.6
+library test;
+
+typedef void F<T>(T t);
+
+class B<T> {
+ void f(F<T> x, int y) {}
+}
+
+abstract class I<T> {
+ void f(F<T> x, Object y);
+}
+
+abstract class C<T> extends B<F<T>> implements I<F<T>> {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/interface_covariantImpl_from_class.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/interface_covariantImpl_from_class.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b877341
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/interface_covariantImpl_from_class.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+// @dart = 2.6
+library test;
+
+abstract class C<T> extends B<F<T>> implements I<F<T>> {}
+
+abstract class I<T> {
+ void f(F<T> x, Object y);
+}
+
+class B<T> {
+ void f(F<T> x, int y) {}
+}
+
+typedef void F<T>(T t);
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/interface_covariantInterface_from_class.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/interface_covariantInterface_from_class.dart.textual_outline.expect
new file mode 100644
index 0000000..6d9f5e3
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/interface_covariantInterface_from_class.dart.textual_outline.expect
@@ -0,0 +1,20 @@
+// @dart = 2.6
+library test;
+
+typedef void F<T>(T t);
+
+abstract class A<T> {
+ void f(T x, int y);
+}
+
+class B<T> implements A<F<T>> {
+ void f(F<T> x, int y) {}
+}
+
+abstract class I<T> implements A<F<T>> {
+ void f(F<T> x, Object y);
+}
+
+abstract class C<T> extends B<F<T>> implements I<F<T>> {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/interface_covariantInterface_from_class.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/interface_covariantInterface_from_class.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ff9bcce
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/interface_covariantInterface_from_class.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+// @dart = 2.6
+library test;
+
+abstract class A<T> {
+ void f(T x, int y);
+}
+
+abstract class C<T> extends B<F<T>> implements I<F<T>> {}
+
+abstract class I<T> implements A<F<T>> {
+ void f(F<T> x, Object y);
+}
+
+class B<T> implements A<F<T>> {
+ void f(F<T> x, int y) {}
+}
+
+typedef void F<T>(T t);
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/invalid_assignment.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/invalid_assignment.dart.textual_outline.expect
new file mode 100644
index 0000000..d8b263a
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/invalid_assignment.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+class A {
+ String operator +(int i) => '';
+}
+
+test(int i, String s, A a) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/invalid_assignment.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/invalid_assignment.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f55ddde
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/invalid_assignment.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+class A {
+ String operator +(int i) => '';
+}
+
+main() {}
+test(int i, String s, A a) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/invalid_cast.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/invalid_cast.dart.textual_outline.expect
new file mode 100644
index 0000000..44ec294
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/invalid_cast.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+// @dart = 2.6
+class C {
+ C();
+ factory C.fact() => null;
+ factory C.fact2() = D;
+ C.nonFact();
+ C.nonFact2() : this.nonFact();
+ static void staticFunction(int i) {}
+}
+
+class D extends C {}
+
+void topLevelFunction(int i) {}
+bad() {}
+ok() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/invalid_cast.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/invalid_cast.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e1bc0c5
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/invalid_cast.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+// @dart = 2.6
+bad() {}
+
+class C {
+ C();
+ C.nonFact();
+ C.nonFact2() : this.nonFact();
+ factory C.fact() => null;
+ factory C.fact2() = D;
+ static void staticFunction(int i) {}
+}
+
+class D extends C {}
+
+main() {}
+ok() {}
+void topLevelFunction(int i) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/invalid_type.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/invalid_type.dart.textual_outline.expect
new file mode 100644
index 0000000..48caf67
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/invalid_type.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+class C {
+ static foo() {}
+}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/invalid_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/invalid_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..499c0b6
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/invalid_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+class C {
+ static foo() {}
+}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/invocations.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/invocations.dart.textual_outline.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/invocations.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/invocations.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/invocations.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/invocations.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue129167943.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue129167943.dart.textual_outline.expect
new file mode 100644
index 0000000..5f82a89
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue129167943.dart.textual_outline.expect
@@ -0,0 +1,56 @@
+// @dart = 2.6
+abstract class A {}
+
+abstract class B {
+ void foo(num x);
+}
+
+abstract class C implements B {
+ void foo(covariant int x);
+}
+
+abstract class D1 implements A, C, B {
+ void foo(covariant int x);
+}
+
+class D2 implements A, C, B {
+ void foo(covariant int x) {}
+}
+
+abstract class D3 implements A, C, B {}
+
+abstract class D4 implements A, C, B {
+ void foo(int x);
+}
+
+abstract class D5 implements A, C, B {
+ void foo(num x);
+}
+
+abstract class E {
+ void set foo(num x);
+}
+
+abstract class G implements E {
+ void set foo(covariant int x);
+}
+
+abstract class H1 implements A, E, G {
+ void set foo(covariant int x);
+}
+
+class H2 implements A, E, G {
+ void set foo(covariant int x) {}
+}
+
+abstract class H3 implements A, E, G {}
+
+abstract class H4 implements A, E, G {
+ void set foo(int x);
+}
+
+abstract class H5 implements A, E, G {
+ void set foo(num x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue129167943.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue129167943.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5031f69
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue129167943.dart.textual_outline_modelled.expect
@@ -0,0 +1,56 @@
+// @dart = 2.6
+abstract class A {}
+
+abstract class B {
+ void foo(num x);
+}
+
+abstract class C implements B {
+ void foo(covariant int x);
+}
+
+abstract class D1 implements A, C, B {
+ void foo(covariant int x);
+}
+
+abstract class D3 implements A, C, B {}
+
+abstract class D4 implements A, C, B {
+ void foo(int x);
+}
+
+abstract class D5 implements A, C, B {
+ void foo(num x);
+}
+
+abstract class E {
+ void set foo(num x);
+}
+
+abstract class G implements E {
+ void set foo(covariant int x);
+}
+
+abstract class H1 implements A, E, G {
+ void set foo(covariant int x);
+}
+
+abstract class H3 implements A, E, G {}
+
+abstract class H4 implements A, E, G {
+ void set foo(int x);
+}
+
+abstract class H5 implements A, E, G {
+ void set foo(num x);
+}
+
+class D2 implements A, C, B {
+ void foo(covariant int x) {}
+}
+
+class H2 implements A, E, G {
+ void set foo(covariant int x) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue34515.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue34515.dart.textual_outline.expect
new file mode 100644
index 0000000..148d7dd
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue34515.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import "issue34515_lib1.dart";
+import "issue34515_lib2.dart";
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue34515.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue34515.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2357783
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue34515.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import "issue34515_lib1.dart";
+import "issue34515_lib2.dart";
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue34899.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue34899.dart.textual_outline.expect
new file mode 100644
index 0000000..45604e7
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue34899.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+// @dart = 2.6
+class Foo<T> {
+ final Future<dynamic> Function() quux;
+ T t;
+ Foo(this.quux, this.t);
+ Future<T> call() => quux().then<T>((_) => t);
+}
+
+class Bar {
+ Foo<Baz> qux;
+ Future<void> quuz() =>
+ qux().then((baz) => corge(baz)).then((grault) => garply(grault));
+ Grault corge(Baz baz) => null;
+ void garply(Grault grault) {}
+}
+
+class Baz {}
+
+class Grault {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue34899.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue34899.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..67e1bed
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue34899.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+// @dart = 2.6
+class Bar {
+ Foo<Baz> qux;
+ Future<void> quuz() =>
+ qux().then((baz) => corge(baz)).then((grault) => garply(grault));
+ Grault corge(Baz baz) => null;
+ void garply(Grault grault) {}
+}
+
+class Baz {}
+
+class Foo<T> {
+ Foo(this.quux, this.t);
+ Future<T> call() => quux().then<T>((_) => t);
+ T t;
+ final Future<dynamic> Function() quux;
+}
+
+class Grault {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue35875.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue35875.dart.textual_outline.expect
new file mode 100644
index 0000000..1db249f
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue35875.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+class A {
+ int a;
+ A(int a) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue35875.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue35875.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1369a93
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue35875.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+class A {
+ A(int a) {}
+ int a;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue37027.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue37027.dart.textual_outline.expect
new file mode 100644
index 0000000..be597eb
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue37027.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+// @dart = 2.6
+class C {
+ final Set<int> s;
+ C(List<int> ell)
+ : s = {
+ for (var e in ell)
+ if (e.isOdd) 2 * e
+ };
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue37027.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue37027.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d3c4d06
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue37027.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+// @dart = 2.6
+class C {
+ C(List<int> ell)
+ : s = {
+ for (var e in ell)
+ if (e.isOdd) 2 * e
+ };
+ final Set<int> s;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue37381.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue37381.dart.textual_outline.expect
new file mode 100644
index 0000000..6761b51
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue37381.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+class A<X> {
+ R f<R>(R Function<X>(A<X>) f) => f<X>(this);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue37381.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue37381.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6761b51
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue37381.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+class A<X> {
+ R f<R>(R Function<X>(A<X>) f) => f<X>(this);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue37776.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue37776.dart.textual_outline.expect
new file mode 100644
index 0000000..a6efc6f
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue37776.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+class X {
+ const X.foo();
+}
+
+class X {
+ const X.foo();
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue37776.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue37776.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a6efc6f
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue37776.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+class X {
+ const X.foo();
+}
+
+class X {
+ const X.foo();
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue38812.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue38812.dart.textual_outline.expect
new file mode 100644
index 0000000..bc1d3b5
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue38812.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+typedef G<X> = void Function();
+
+class A<X extends G<A<Y, X>>, Y extends G<A<X, Y>>> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue38812.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue38812.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3a99d60
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue38812.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+class A<X extends G<A<Y, X>>, Y extends G<A<X, Y>>> {}
+
+main() {}
+typedef G<X> = void Function();
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue38938.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue38938.dart.textual_outline.expect
new file mode 100644
index 0000000..82a3e53
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue38938.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+class A {
+ int v;
+ int v;
+ A(this.v);
+ A.second();
+}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue38938.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue38938.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6f239ae
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue38938.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+class A {
+ A(this.v);
+ A.second();
+ int v;
+ int v;
+}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue38943.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue38943.dart.textual_outline.expect
new file mode 100644
index 0000000..84dc47f
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue38943.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+class D<X extends void Function()> {
+ factory D.foo() => new D._();
+ D._() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue38943.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue38943.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a160055
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue38943.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+class D<X extends void Function()> {
+ D._() {}
+ factory D.foo() => new D._();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue38944.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue38944.dart.textual_outline.expect
new file mode 100644
index 0000000..3b0969c
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue38944.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+class A<Q> {}
+
+class B<X> extends Object with A<void Function<Y extends X>()> {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue38944.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue38944.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3b0969c
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue38944.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+class A<Q> {}
+
+class B<X> extends Object with A<void Function<Y extends X>()> {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue38961.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue38961.dart.textual_outline.expect
new file mode 100644
index 0000000..41ad065
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue38961.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+class C {
+ dynamic x = this;
+ var x = this;
+}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue38961.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue38961.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..41ad065
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue38961.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+class C {
+ dynamic x = this;
+ var x = this;
+}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue39344.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue39344.dart.textual_outline.expect
new file mode 100644
index 0000000..9226278
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue39344.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+// @dart = 2.6
+class A {}
+
+class B extends A {}
+
+List<B> xs;
+List<List<B>> xss;
+
+class Class<T extends A> {
+ void method1a(T t) {}
+ void method1b(T t) {}
+ void method2a(T t) {}
+ void method2b(T t) {}
+}
+
+void main() {}
+void errors() {}
+void throws(void Function() f) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue39344.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue39344.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ba257d0
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue39344.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+// @dart = 2.6
+List<B> xs;
+List<List<B>> xss;
+
+class A {}
+
+class B extends A {}
+
+class Class<T extends A> {
+ void method1a(T t) {}
+ void method1b(T t) {}
+ void method2a(T t) {}
+ void method2b(T t) {}
+}
+
+void errors() {}
+void main() {}
+void throws(void Function() f) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart.textual_outline.expect
new file mode 100644
index 0000000..b597c8a
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+class A {}
+
+class A {}
+
+class B {
+ foo(List<Null> a) {}
+}
+
+class C extends B {
+ foo(List<A> a) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b597c8a
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue39421.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+class A {}
+
+class A {}
+
+class B {
+ foo(List<Null> a) {}
+}
+
+class C extends B {
+ foo(List<A> a) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue39817.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue39817.dart.textual_outline.expect
new file mode 100644
index 0000000..41dbdca
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue39817.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue39817.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue39817.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..41dbdca
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue39817.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/literals.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/literals.dart.textual_outline.expect
new file mode 100644
index 0000000..4ac4f62
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/literals.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+testString() {}
+testInt() {}
+testBool() {}
+testDouble() {}
+testNull() {}
+testList() {}
+testMap() {}
+testSymbol() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/literals.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/literals.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ae913a9
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/literals.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+main() {}
+testBool() {}
+testDouble() {}
+testInt() {}
+testList() {}
+testMap() {}
+testNull() {}
+testString() {}
+testSymbol() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/local_generic_function.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/local_generic_function.dart.textual_outline.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/local_generic_function.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/local_generic_function.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/local_generic_function.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/local_generic_function.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/long_chain_of_typedefs.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/long_chain_of_typedefs.dart.textual_outline.expect
new file mode 100644
index 0000000..0c87ff5
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/long_chain_of_typedefs.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+// @dart = 2.6
+typedef Foo01<X, Y, Z> = void Function(Null);
+typedef Foo02<X, Y, Z> = void Function(Foo01<X, Y, Z>);
+typedef Foo03<X, Y, Z> = void Function(Foo02<X, Y, Z>);
+typedef Foo04<X, Y, Z> = void Function(Foo03<X, Y, Z>);
+typedef Foo05<X, Y, Z> = void Function(Foo04<X, Y, Z>);
+typedef Foo06<X, Y, Z> = void Function(Foo05<X, Y, Z>);
+typedef Foo07<X, Y, Z> = void Function(Foo06<X, Y, Z>);
+typedef Foo08<X, Y, Z> = void Function(Foo07<X, Y, Z>);
+typedef Foo09<X, Y, Z> = void Function(Foo08<X, Y, Z>);
+typedef Foo10<X, Y, Z> = void Function(Foo09<X, Y, Z>);
+typedef Foo11<X, Y, Z> = void Function(Foo10<X, Y, Z>);
+typedef Foo12<X, Y, Z> = void Function(Foo11<X, Y, Z>);
+typedef Foo13<X, Y, Z> = void Function(Foo12<X, Y, Z>);
+typedef Foo14<X, Y, Z> = void Function(Foo13<X, Y, Z>);
+typedef Foo15<X, Y, Z> = void Function(Foo14<X, Y, Z>);
+typedef Foo16<X, Y, Z> = void Function(Foo15<X, Y, Z>);
+typedef Foo17<X, Y, Z> = void Function(Foo16<X, Y, Z>);
+typedef Foo18<X, Y, Z> = void Function(Foo17<X, Y, Z>);
+typedef Foo19<X, Y, Z> = void Function(Foo18<X, Y, Z>);
+typedef Foo20<X, Y, Z> = void Function(Foo19<X, Y, Z>);
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/long_chain_of_typedefs.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/long_chain_of_typedefs.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..62fc26e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/long_chain_of_typedefs.dart.textual_outline_modelled.expect
@@ -0,0 +1,22 @@
+// @dart = 2.6
+main() {}
+typedef Foo01<X, Y, Z> = void Function(Null);
+typedef Foo02<X, Y, Z> = void Function(Foo01<X, Y, Z>);
+typedef Foo03<X, Y, Z> = void Function(Foo02<X, Y, Z>);
+typedef Foo04<X, Y, Z> = void Function(Foo03<X, Y, Z>);
+typedef Foo05<X, Y, Z> = void Function(Foo04<X, Y, Z>);
+typedef Foo06<X, Y, Z> = void Function(Foo05<X, Y, Z>);
+typedef Foo07<X, Y, Z> = void Function(Foo06<X, Y, Z>);
+typedef Foo08<X, Y, Z> = void Function(Foo07<X, Y, Z>);
+typedef Foo09<X, Y, Z> = void Function(Foo08<X, Y, Z>);
+typedef Foo10<X, Y, Z> = void Function(Foo09<X, Y, Z>);
+typedef Foo11<X, Y, Z> = void Function(Foo10<X, Y, Z>);
+typedef Foo12<X, Y, Z> = void Function(Foo11<X, Y, Z>);
+typedef Foo13<X, Y, Z> = void Function(Foo12<X, Y, Z>);
+typedef Foo14<X, Y, Z> = void Function(Foo13<X, Y, Z>);
+typedef Foo15<X, Y, Z> = void Function(Foo14<X, Y, Z>);
+typedef Foo16<X, Y, Z> = void Function(Foo15<X, Y, Z>);
+typedef Foo17<X, Y, Z> = void Function(Foo16<X, Y, Z>);
+typedef Foo18<X, Y, Z> = void Function(Foo17<X, Y, Z>);
+typedef Foo19<X, Y, Z> = void Function(Foo18<X, Y, Z>);
+typedef Foo20<X, Y, Z> = void Function(Foo19<X, Y, Z>);
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/magic_const.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/magic_const.dart.textual_outline.expect
new file mode 100644
index 0000000..ee3bb292
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/magic_const.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+class Constant {
+ const Constant();
+}
+
+class NotConstant {}
+
+foo({a: Constant(), b: Constant(), c: []}) {}
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/magic_const.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/magic_const.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7c029de
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/magic_const.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+class Constant {
+ const Constant();
+}
+
+class NotConstant {}
+
+foo({a: Constant(), b: Constant(), c: []}) {}
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/many_errors.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/many_errors.dart.textual_outline.expect
new file mode 100644
index 0000000..32bba3e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/many_errors.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+// @dart = 2.6
+class A {
+ final x = null;
+ const A.named1() sync* { }
+ const A.named2() : x = new Object();
+}
+external foo(String x) { }
+class B {
+}
+class C {
+ B b;
+}
+abstract class AbstractClass {
+ const AbstractClass.id();
+}
+m() { }
+main() { }
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/map.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/map.dart.textual_outline.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/map.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/map.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/map.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/map.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/metadata_enum.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/metadata_enum.dart.textual_outline.expect
new file mode 100644
index 0000000..0bccd4a
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/metadata_enum.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+const a = null;
+@a
+enum E { E1, E2, E3 }
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/metadata_enum.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/metadata_enum.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..591a2e5
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/metadata_enum.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+@a
+enum E { E1, E2, E3 }
+const a = null;
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/metadata_named_mixin_application.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/metadata_named_mixin_application.dart.textual_outline.expect
new file mode 100644
index 0000000..73fde59
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/metadata_named_mixin_application.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+const a = null;
+@a
+class C = D with E;
+
+class D {}
+
+class E {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/metadata_named_mixin_application.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/metadata_named_mixin_application.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..02cfd25
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/metadata_named_mixin_application.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+@a
+const a = null;
+class C = D with E;
+
+class D {}
+
+class E {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/micro.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/micro.dart.textual_outline.expect
new file mode 100644
index 0000000..cb155f6
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/micro.dart.textual_outline.expect
@@ -0,0 +1,43 @@
+// @dart = 2.6
+staticMethod() {}
+
+class Foo {
+ instanceMethod() {}
+}
+
+external bool externalStatic();
+
+abstract class ExternalValue {}
+
+abstract class Bar {
+ ExternalValue externalInstanceMethod();
+}
+
+external Bar createBar();
+
+class Box {
+ var field;
+}
+
+stringArgument(x) {}
+intArgument(x) {}
+
+class FinalBox {
+ final finalField;
+ FinalBox(this.finalField);
+}
+
+class SubFinalBox extends FinalBox {
+ SubFinalBox(value) : super(value);
+}
+
+class DynamicReceiver1 {
+ dynamicallyCalled(x) {}
+}
+
+class DynamicReceiver2 {
+ dynamicallyCalled(x) {}
+}
+
+void makeDynamicCall(receiver) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/micro.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/micro.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a927605
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/micro.dart.textual_outline_modelled.expect
@@ -0,0 +1,39 @@
+// @dart = 2.6
+abstract class Bar {
+ ExternalValue externalInstanceMethod();
+}
+
+abstract class ExternalValue {}
+
+class Box {
+ var field;
+}
+
+class DynamicReceiver1 {
+ dynamicallyCalled(x) {}
+}
+
+class DynamicReceiver2 {
+ dynamicallyCalled(x) {}
+}
+
+class FinalBox {
+ FinalBox(this.finalField);
+ final finalField;
+}
+
+class Foo {
+ instanceMethod() {}
+}
+
+class SubFinalBox extends FinalBox {
+ SubFinalBox(value) : super(value);
+}
+
+external Bar createBar();
+external bool externalStatic();
+intArgument(x) {}
+main() {}
+staticMethod() {}
+stringArgument(x) {}
+void makeDynamicCall(receiver) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/minimum_int.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/minimum_int.dart.textual_outline.expect
new file mode 100644
index 0000000..4b5a61c
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/minimum_int.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() => print(-9223372036854775808);
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/minimum_int.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/minimum_int.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4b5a61c
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/minimum_int.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() => print(-9223372036854775808);
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/missing_constructor.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/missing_constructor.dart.textual_outline.expect
new file mode 100644
index 0000000..f2b9597
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/missing_constructor.dart.textual_outline.expect
@@ -0,0 +1,23 @@
+// @dart = 2.6
+class Super {
+ Super._();
+}
+
+class Sub extends Super {
+ Sub() : super();
+ Sub.foo() : super.foo();
+}
+
+class Bad {
+ Bad.foo() : this();
+ Bad.bar() : this.baz();
+}
+
+class M {}
+
+class MixinApplication extends Super with M {
+ MixinApplication() : super();
+ MixinApplication.foo() : super.foo();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/missing_constructor.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/missing_constructor.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..06f8c69
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/missing_constructor.dart.textual_outline_modelled.expect
@@ -0,0 +1,23 @@
+// @dart = 2.6
+class Bad {
+ Bad.bar() : this.baz();
+ Bad.foo() : this();
+}
+
+class M {}
+
+class MixinApplication extends Super with M {
+ MixinApplication() : super();
+ MixinApplication.foo() : super.foo();
+}
+
+class Sub extends Super {
+ Sub() : super();
+ Sub.foo() : super.foo();
+}
+
+class Super {
+ Super._();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/missing_toplevel.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/missing_toplevel.dart.textual_outline.expect
new file mode 100644
index 0000000..c8b0fa8
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/missing_toplevel.dart.textual_outline.expect
@@ -0,0 +1,28 @@
+// @dart = 2.6
+class EmptyClass {}
+
+var emptyClass = new EmptyClass();
+
+class ClassWithProperty {
+ EmptyClass property;
+}
+
+var classWithProperty = new ClassWithProperty();
+
+class ClassWithIndexSet {
+ operator []=(int index, int value) {}
+}
+
+var classWithIndexSet = new ClassWithIndexSet();
+
+class ClassWithIndexGet {
+ int operator [](int index) => 42;
+}
+
+var classWithIndexGet = new ClassWithIndexGet();
+var missingBinary = classWithProperty.property += 2;
+var missingIndexGet = classWithIndexSet[0] ??= 2;
+var missingIndexSet = classWithIndexGet[0] ??= 2;
+var missingPropertyGet = emptyClass.property;
+var missingPropertySet = emptyClass.property = 42;
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/missing_toplevel.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/missing_toplevel.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..16d597a
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/missing_toplevel.dart.textual_outline_modelled.expect
@@ -0,0 +1,25 @@
+// @dart = 2.6
+class ClassWithIndexGet {
+ int operator [](int index) => 42;
+}
+
+class ClassWithIndexSet {
+ operator []=(int index, int value) {}
+}
+
+class ClassWithProperty {
+ EmptyClass property;
+}
+
+class EmptyClass {}
+
+main() {}
+var classWithIndexGet = new ClassWithIndexGet();
+var classWithIndexSet = new ClassWithIndexSet();
+var classWithProperty = new ClassWithProperty();
+var emptyClass = new EmptyClass();
+var missingBinary = classWithProperty.property += 2;
+var missingIndexGet = classWithIndexSet[0] ??= 2;
+var missingIndexSet = classWithIndexGet[0] ??= 2;
+var missingPropertyGet = emptyClass.property;
+var missingPropertySet = emptyClass.property = 42;
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/mixin.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/mixin.dart.textual_outline.expect
new file mode 100644
index 0000000..f50acc7
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/mixin.dart.textual_outline.expect
@@ -0,0 +1,24 @@
+// @dart = 2.6
+class B extends Object with M1, M2 {
+ B(value);
+}
+
+abstract class M1 {
+ m() => print("M1");
+}
+
+abstract class M2 {
+ m() => print("M2");
+}
+
+class C extends Object with M1, M2 {
+ C(value);
+}
+
+abstract class G1<T> {
+ m() => print(T);
+}
+
+class D<S> extends Object with G1<S> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/mixin.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/mixin.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..efc6453
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/mixin.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+// @dart = 2.6
+abstract class G1<T> {
+ m() => print(T);
+}
+
+abstract class M1 {
+ m() => print("M1");
+}
+
+abstract class M2 {
+ m() => print("M2");
+}
+
+class B extends Object with M1, M2 {
+ B(value);
+}
+
+class C extends Object with M1, M2 {
+ C(value);
+}
+
+class D<S> extends Object with G1<S> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/mixin_application_inferred_parameter_type.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_application_inferred_parameter_type.dart.textual_outline.expect
new file mode 100644
index 0000000..977b29e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_application_inferred_parameter_type.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+// @dart = 2.6
+class Mixin {}
+
+class Super {
+ var field = 42;
+ Super(this.field);
+}
+
+class Class = Super with Mixin;
+main() {}
+error() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/mixin_application_inferred_parameter_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_application_inferred_parameter_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bfdb845
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_application_inferred_parameter_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+// @dart = 2.6
+class Mixin {}
+
+class Super {
+ Super(this.field);
+ var field = 42;
+}
+
+class Class = Super with Mixin;
+error() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/mixin_application_override.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_application_override.dart.textual_outline.expect
new file mode 100644
index 0000000..ad2f273
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_application_override.dart.textual_outline.expect
@@ -0,0 +1,35 @@
+// @dart = 2.6
+class S {
+ foo([x]) {}
+}
+
+class M {
+ foo() {}
+}
+
+class M1 {}
+
+class M2 {}
+
+class MX {}
+
+class A0 = S with M;
+class A1 = S with M1, M;
+class A2 = S with M1, M2, M;
+class A0X = S with M, MX;
+class A1X = S with M1, M, MX;
+class A2X = S with M1, M2, M, MX;
+
+class B0 extends S with M {}
+
+class B1 extends S with M1, M {}
+
+class B2 extends S with M1, M2, M {}
+
+class B0X extends S with M, MX {}
+
+class B1X extends S with M1, M, MX {}
+
+class B2X extends S with M1, M2, M, MX {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/mixin_application_override.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_application_override.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ed18e1c
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_application_override.dart.textual_outline_modelled.expect
@@ -0,0 +1,35 @@
+// @dart = 2.6
+class M {
+ foo() {}
+}
+
+class M1 {}
+
+class M2 {}
+
+class MX {}
+
+class S {
+ foo([x]) {}
+}
+
+class A0 = S with M;
+class A1 = S with M1, M;
+class A2 = S with M1, M2, M;
+class A0X = S with M, MX;
+class A1X = S with M1, M, MX;
+class A2X = S with M1, M2, M, MX;
+
+class B0 extends S with M {}
+
+class B0X extends S with M, MX {}
+
+class B1 extends S with M1, M {}
+
+class B1X extends S with M1, M, MX {}
+
+class B2 extends S with M1, M2, M {}
+
+class B2X extends S with M1, M2, M, MX {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/mixin_conflicts.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_conflicts.dart.textual_outline.expect
new file mode 100644
index 0000000..65b69bb
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_conflicts.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+// @dart = 2.6
+class M {
+ foo() {}
+}
+
+class N = Object with M;
+
+class C extends Object with N {}
+
+abstract class M2 implements M {
+ bar() {}
+}
+
+class N2 = Object with M2;
+abstract class N3 = Object with M2;
+
+class C2 extends Object with M2 {}
+
+abstract class C3 extends Object with M2 {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/mixin_conflicts.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_conflicts.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6d6b9fb
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_conflicts.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+// @dart = 2.6
+class M {
+ foo() {}
+}
+
+class N = Object with M;
+
+abstract class M2 implements M {
+ bar() {}
+}
+
+class C extends Object with N {}
+
+class N2 = Object with M2;
+abstract class N3 = Object with M2;
+
+abstract class C3 extends Object with M2 {}
+
+class C2 extends Object with M2 {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/mixin_constructors_with_default_values.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_constructors_with_default_values.dart.textual_outline.expect
new file mode 100644
index 0000000..e5cb16d
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_constructors_with_default_values.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+// @dart = 2.6
+import "package:expect/expect.dart";
+
+class C<T> {
+ String trace;
+ C({a: 0, b: T}) : trace = "a: $a, b: $b";
+}
+
+class M {}
+
+class D = C<String> with M;
+
+class E extends D {}
+
+class F extends C<int> with M {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/mixin_constructors_with_default_values.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_constructors_with_default_values.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fd7c911
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_constructors_with_default_values.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+// @dart = 2.6
+import "package:expect/expect.dart";
+
+class C<T> {
+ C({a: 0, b: T}) : trace = "a: $a, b: $b";
+ String trace;
+}
+
+class M {}
+
+class D = C<String> with M;
+
+class E extends D {}
+
+class F extends C<int> with M {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/mixin_inherited_setter_for_mixed_in_field.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_inherited_setter_for_mixed_in_field.dart.textual_outline.expect
new file mode 100644
index 0000000..5c4acda
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_inherited_setter_for_mixed_in_field.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+// @dart = 2.6
+class A {}
+
+class C<T extends A> {
+ T _field;
+ foo(T x) {}
+}
+
+class D extends C<B> {}
+
+class Foo extends Object with C<B> {}
+
+class B extends A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/mixin_inherited_setter_for_mixed_in_field.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_inherited_setter_for_mixed_in_field.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c765f3a
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_inherited_setter_for_mixed_in_field.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+// @dart = 2.6
+class A {}
+
+class B extends A {}
+
+class C<T extends A> {
+ T _field;
+ foo(T x) {}
+}
+
+class D extends C<B> {}
+
+class Foo extends Object with C<B> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/mixin_super_repeated.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_super_repeated.dart.textual_outline.expect
new file mode 100644
index 0000000..0a4bcf8
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_super_repeated.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+abstract class M {
+ var m;
+}
+
+abstract class N extends M {
+ void set superM(value) {}
+ get superM => super.m;
+}
+
+class S {}
+
+class Named = S with M, N, M;
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/mixin_super_repeated.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_super_repeated.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e41069c
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_super_repeated.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+abstract class M {
+ var m;
+}
+
+abstract class N extends M {
+ get superM => super.m;
+ void set superM(value) {}
+}
+
+class S {}
+
+class Named = S with M, N, M;
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/mixin_with_static_member.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_with_static_member.dart.textual_outline.expect
new file mode 100644
index 0000000..8cbf995
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_with_static_member.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+// @dart = 2.6
+class A extends B with M {}
+
+class B {
+ final Object m = null;
+}
+
+class M {
+ static Object m() => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/mixin_with_static_member.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_with_static_member.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8cbf995
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/mixin_with_static_member.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+// @dart = 2.6
+class A extends B with M {}
+
+class B {
+ final Object m = null;
+}
+
+class M {
+ static Object m() => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/named_function_scope.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/named_function_scope.dart.textual_outline.expect
new file mode 100644
index 0000000..2cdd1a7
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/named_function_scope.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+class T {}
+
+class V {}
+
+test() {}
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/named_function_scope.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/named_function_scope.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2cdd1a7
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/named_function_scope.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+class T {}
+
+class V {}
+
+test() {}
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/named_parameters.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/named_parameters.dart.textual_outline.expect
new file mode 100644
index 0000000..c269fb4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/named_parameters.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+// @dart = 2.6
+class Superclass {
+ foo({alpha, beta}) {}
+ bar({beta, alpha}) {}
+ namedCallback(callback({String alpha, int beta})) {}
+}
+
+class Subclass extends Superclass {
+ foo({beta, alpha}) {}
+ bar({alpha, beta}) {}
+ namedCallback(callback({int beta, String alpha})) {}
+}
+
+topLevelNamed(beta, alpha, {gamma, delta}) {}
+topLevelOptional(beta, alpha, [gamma, delta]) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/named_parameters.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/named_parameters.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..07b9e96
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/named_parameters.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+// @dart = 2.6
+class Subclass extends Superclass {
+ bar({alpha, beta}) {}
+ foo({beta, alpha}) {}
+ namedCallback(callback({int beta, String alpha})) {}
+}
+
+class Superclass {
+ bar({beta, alpha}) {}
+ foo({alpha, beta}) {}
+ namedCallback(callback({String alpha, int beta})) {}
+}
+
+main() {}
+topLevelNamed(beta, alpha, {gamma, delta}) {}
+topLevelOptional(beta, alpha, [gamma, delta]) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/native_as_name.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/native_as_name.dart.textual_outline.expect
new file mode 100644
index 0000000..f9ea52b
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/native_as_name.dart.textual_outline.expect
@@ -0,0 +1,25 @@
+// @dart = 2.6
+main() {}
+
+class W {
+ String native;
+ W() : native = "field";
+}
+
+class X {
+ String native() => "method";
+}
+
+abstract class Y1 {
+ String get native;
+}
+
+class Y2 extends Y1 {
+ @override
+ String get native => "getter";
+}
+
+class Z {
+ set native(String s) => f = s;
+ String f;
+}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/native_as_name.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/native_as_name.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..dea0ab9
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/native_as_name.dart.textual_outline_modelled.expect
@@ -0,0 +1,25 @@
+// @dart = 2.6
+abstract class Y1 {
+ String get native;
+}
+
+class W {
+ String native;
+ W() : native = "field";
+}
+
+class X {
+ String native() => "method";
+}
+
+class Y2 extends Y1 {
+ @override
+ String get native => "getter";
+}
+
+class Z {
+ String f;
+ set native(String s) => f = s;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/nested_implicit_const_with_env_var.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/nested_implicit_const_with_env_var.dart.textual_outline.expect
new file mode 100644
index 0000000..f881723
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/nested_implicit_const_with_env_var.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+// @dart = 2.6
+const int foo = const int.fromEnvironment("fisk");
+
+class A {
+ final int bar;
+ const A(this.bar);
+}
+
+class B {
+ final A baz;
+ const B(this.baz);
+}
+
+class C {
+ fun() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/nested_implicit_const_with_env_var.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/nested_implicit_const_with_env_var.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f951d0e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/nested_implicit_const_with_env_var.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+// @dart = 2.6
+class A {
+ const A(this.bar);
+ final int bar;
+}
+
+class B {
+ const B(this.baz);
+ final A baz;
+}
+
+class C {
+ fun() {}
+}
+
+const int foo = const int.fromEnvironment("fisk");
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/nested_property_set.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/nested_property_set.dart.textual_outline.expect
new file mode 100644
index 0000000..7feca64
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/nested_property_set.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+class NumField {
+ num field;
+}
+
+class IntField {
+ int field;
+}
+
+class DoubleField {
+ double field;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/nested_property_set.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/nested_property_set.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6053fe8
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/nested_property_set.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+class DoubleField {
+ double field;
+}
+
+class IntField {
+ int field;
+}
+
+class NumField {
+ num field;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/nested_variable_set.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/nested_variable_set.dart.textual_outline.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/nested_variable_set.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/nested_variable_set.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/nested_variable_set.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/nested_variable_set.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/nested_variance.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/nested_variance.dart.textual_outline.expect
new file mode 100644
index 0000000..f6f8d28
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/nested_variance.dart.textual_outline.expect
@@ -0,0 +1,53 @@
+// @dart = 2.6
+typedef F<X> = void Function<Y extends X>();
+F<X> toF<X>(X x) => null;
+typedef Fcov<X> = X Function();
+typedef Fcon<X> = Function(X);
+typedef Finv<X> = X Function(X);
+
+class Acov<X extends Fcov<Y>, Y> {}
+
+class Acon<X extends Fcon<Y>, Y> {}
+
+class Ainv<X extends Finv<Y>, Y> {}
+
+typedef FcovBound<X extends num> = X Function();
+typedef FconBound<X extends num> = Function(X);
+typedef FinvBound<X extends num> = X Function(X);
+
+class AcovBound<X extends FcovBound<Y>, Y extends num> {}
+
+class AconBound<X extends FconBound<Y>, Y extends num> {}
+
+class AinvBound<X extends FinvBound<Y>, Y extends num> {}
+
+class A<X> {}
+
+typedef FcovCyclicBound<X extends A<X>> = X Function();
+typedef FconCyclicBound<X extends A<X>> = Function(X);
+typedef FinvCyclicBound<X extends A<X>> = X Function(X);
+
+class AcovCyclicBound<X extends FcovCyclicBound<Y>, Y extends A<Y>> {}
+
+class AconCyclicBound<X extends FconCyclicBound<Y>, Y extends A<Y>> {}
+
+class AinvCyclicBound<X extends FinvCyclicBound<Y>, Y extends A<Y>> {}
+
+typedef FcovCyclicCoBound<X extends Function(X)> = X Function();
+typedef FconCyclicCoBound<X extends Function(X)> = Function(X);
+typedef FinvCyclicCoBound<X extends Function(X)> = X Function(X);
+
+class AcovCyclicCoBound<X extends FcovCyclicCoBound<Y>, Y extends Function(Y)> {
+}
+
+class AconCyclicCoBound<X extends FconCyclicCoBound<Y>, Y extends Function(Y)> {
+}
+
+class AinvCyclicCoBound<X extends FinvCyclicCoBound<Y>, Y extends Function(Y)> {
+}
+
+class B<X> {}
+
+void testTypeAliasAsTypeArgument() {}
+void testNested() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/nested_variance.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/nested_variance.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..402b4d5
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/nested_variance.dart.textual_outline_modelled.expect
@@ -0,0 +1,50 @@
+// @dart = 2.6
+F<X> toF<X>(X x) => null;
+
+class A<X> {}
+
+class Acon<X extends Fcon<Y>, Y> {}
+
+class AconBound<X extends FconBound<Y>, Y extends num> {}
+
+class AconCyclicBound<X extends FconCyclicBound<Y>, Y extends A<Y>> {}
+
+class AconCyclicCoBound<X extends FconCyclicCoBound<Y>, Y extends Function(Y)> {
+}
+
+class Acov<X extends Fcov<Y>, Y> {}
+
+class AcovBound<X extends FcovBound<Y>, Y extends num> {}
+
+class AcovCyclicBound<X extends FcovCyclicBound<Y>, Y extends A<Y>> {}
+
+class AcovCyclicCoBound<X extends FcovCyclicCoBound<Y>, Y extends Function(Y)> {
+}
+
+class Ainv<X extends Finv<Y>, Y> {}
+
+class AinvBound<X extends FinvBound<Y>, Y extends num> {}
+
+class AinvCyclicBound<X extends FinvCyclicBound<Y>, Y extends A<Y>> {}
+
+class AinvCyclicCoBound<X extends FinvCyclicCoBound<Y>, Y extends Function(Y)> {
+}
+
+class B<X> {}
+
+main() {}
+typedef F<X> = void Function<Y extends X>();
+typedef Fcon<X> = Function(X);
+typedef FconBound<X extends num> = Function(X);
+typedef FconCyclicBound<X extends A<X>> = Function(X);
+typedef FconCyclicCoBound<X extends Function(X)> = Function(X);
+typedef Fcov<X> = X Function();
+typedef FcovBound<X extends num> = X Function();
+typedef FcovCyclicBound<X extends A<X>> = X Function();
+typedef FcovCyclicCoBound<X extends Function(X)> = X Function();
+typedef Finv<X> = X Function(X);
+typedef FinvBound<X extends num> = X Function(X);
+typedef FinvCyclicBound<X extends A<X>> = X Function(X);
+typedef FinvCyclicCoBound<X extends Function(X)> = X Function(X);
+void testNested() {}
+void testTypeAliasAsTypeArgument() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/no_such_method_private_setter.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/no_such_method_private_setter.dart.textual_outline.expect
new file mode 100644
index 0000000..65d942d
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/no_such_method_private_setter.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import './no_such_method_private_setter_lib.dart';
+
+class Foo implements Bar {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/no_such_method_private_setter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/no_such_method_private_setter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..65d942d
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/no_such_method_private_setter.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import './no_such_method_private_setter_lib.dart';
+
+class Foo implements Bar {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/non_covariant_checks.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/non_covariant_checks.dart.textual_outline.expect
new file mode 100644
index 0000000..4184ffb
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/non_covariant_checks.dart.textual_outline.expect
@@ -0,0 +1,80 @@
+// @dart = 2.6
+class C<T> {
+ C(this.field1)
+ : field2 = (() => field1),
+ field3 = ((T t) {}),
+ field4 = ((T t) => t),
+ field5 = (() => () => field1),
+ field6 = ((T Function() f) {}),
+ field7 = ((T Function() f) => field1),
+ field8 = ((void Function(T) f) {}),
+ field9 = ((void Function(T) f) => field1),
+ field10 = ((T Function(T) f) {}),
+ field11 = ((T Function(T) f) => field1),
+ field12 = <S extends T>() => null,
+ field13 = <S extends T>(S s) {},
+ field14 = <S extends T>(S s) => s,
+ field15 = ((S Function<S extends T>() f) {});
+ T field1;
+ T Function() field2;
+ void Function(T) field3;
+ T Function(T) field4;
+ T Function() Function() field5;
+ void Function(T Function()) field6;
+ T Function(T Function()) field7;
+ void Function(void Function(T)) field8;
+ T Function(void Function(T)) field9;
+ void Function(T Function(T)) field10;
+ T Function(T Function(T)) field11;
+ S Function<S extends T>() field12;
+ void Function<S extends T>(S) field13;
+ S Function<S extends T>(S) field14;
+ void Function(S Function<S extends T>()) field15;
+ T get getter1 => field1;
+ T Function() get getter2 => field2;
+ void Function(T) get getter3 => field3;
+ T Function(T) get getter4 => field4;
+ T Function() Function() get getter5 => field5;
+ void Function(T Function()) get getter6 => field6;
+ T Function(T Function()) get getter7 => field7;
+ void Function(void Function(T)) get getter8 => field8;
+ T Function(void Function(T)) get getter9 => field9;
+ void Function(T Function(T)) get getter10 => field10;
+ T Function(T Function(T)) get getter11 => field11;
+ S Function<S extends T>() get getter12 => field12;
+ void Function<S extends T>(S) get getter13 => field13;
+ S Function<S extends T>(S) get getter14 => field14;
+ void Function(S Function<S extends T>()) get getter15 => field15;
+ void set setter1(T value) {}
+ void set setter2(T Function() value) {}
+ void set setter3(void Function(T) value) {}
+ void set setter4(T Function(T) value) {}
+ void set setter5(T Function() Function() value) {}
+ void set setter6(void Function(T Function()) value) {}
+ void set setter7(T Function(T Function()) value) {}
+ void set setter8(void Function(void Function(T)) value) {}
+ void set setter9(T Function(void Function(T)) value) {}
+ void set setter10(void Function(T Function(T)) value) {}
+ void set setter11(T Function(T Function(T)) value) {}
+ void set setter12(S Function<S extends T>() value) {}
+ void set setter13(void Function<S extends T>(S) value) {}
+ void set setter14(S Function<S extends T>(S) value) {}
+ void set setter15(void Function(S Function<S extends T>()) value) {}
+ void method1(T value) {}
+ void method2(T Function() value) {}
+ void method3(void Function(T) value) {}
+ void method4(T Function(T) value) {}
+ void method5(T Function() Function() value) {}
+ void method6(void Function(T Function()) value) {}
+ void method7(T Function(T Function()) value) {}
+ void method8(void Function(void Function(T)) value) {}
+ void method9(T Function(void Function(T)) value) {}
+ void method10(void Function(T Function(T)) value) {}
+ void method11(T Function(T Function(T)) value) {}
+ void method12(S Function<S extends T>() value) {}
+ void method13(void Function<S extends T>(S) value) {}
+ void method14(S Function<S extends T>(S) value) {}
+ void method15(void Function(S Function<S extends T>()) value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/non_covariant_checks.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/non_covariant_checks.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6969145
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/non_covariant_checks.dart.textual_outline_modelled.expect
@@ -0,0 +1,80 @@
+// @dart = 2.6
+class C<T> {
+ C(this.field1)
+ : field2 = (() => field1),
+ field3 = ((T t) {}),
+ field4 = ((T t) => t),
+ field5 = (() => () => field1),
+ field6 = ((T Function() f) {}),
+ field7 = ((T Function() f) => field1),
+ field8 = ((void Function(T) f) {}),
+ field9 = ((void Function(T) f) => field1),
+ field10 = ((T Function(T) f) {}),
+ field11 = ((T Function(T) f) => field1),
+ field12 = <S extends T>() => null,
+ field13 = <S extends T>(S s) {},
+ field14 = <S extends T>(S s) => s,
+ field15 = ((S Function<S extends T>() f) {});
+ S Function<S extends T>() field12;
+ S Function<S extends T>() get getter12 => field12;
+ S Function<S extends T>(S) field14;
+ S Function<S extends T>(S) get getter14 => field14;
+ T Function(T Function()) field7;
+ T Function(T Function()) get getter7 => field7;
+ T Function(T Function(T)) field11;
+ T Function(T Function(T)) get getter11 => field11;
+ T Function(T) field4;
+ T Function(T) get getter4 => field4;
+ T Function() Function() field5;
+ T Function() Function() get getter5 => field5;
+ T Function() field2;
+ T Function() get getter2 => field2;
+ T Function(void Function(T)) field9;
+ T Function(void Function(T)) get getter9 => field9;
+ T field1;
+ T get getter1 => field1;
+ void Function(T Function()) field6;
+ void Function(T Function()) get getter6 => field6;
+ void Function(T Function(T)) field10;
+ void Function(T Function(T)) get getter10 => field10;
+ void Function(T) field3;
+ void Function(T) get getter3 => field3;
+ void Function(S Function<S extends T>()) field15;
+ void Function(S Function<S extends T>()) get getter15 => field15;
+ void Function(void Function(T)) field8;
+ void Function(void Function(T)) get getter8 => field8;
+ void Function<S extends T>(S) field13;
+ void Function<S extends T>(S) get getter13 => field13;
+ void method1(T value) {}
+ void method10(void Function(T Function(T)) value) {}
+ void method11(T Function(T Function(T)) value) {}
+ void method12(S Function<S extends T>() value) {}
+ void method13(void Function<S extends T>(S) value) {}
+ void method14(S Function<S extends T>(S) value) {}
+ void method15(void Function(S Function<S extends T>()) value) {}
+ void method2(T Function() value) {}
+ void method3(void Function(T) value) {}
+ void method4(T Function(T) value) {}
+ void method5(T Function() Function() value) {}
+ void method6(void Function(T Function()) value) {}
+ void method7(T Function(T Function()) value) {}
+ void method8(void Function(void Function(T)) value) {}
+ void method9(T Function(void Function(T)) value) {}
+ void set setter1(T value) {}
+ void set setter10(void Function(T Function(T)) value) {}
+ void set setter11(T Function(T Function(T)) value) {}
+ void set setter12(S Function<S extends T>() value) {}
+ void set setter13(void Function<S extends T>(S) value) {}
+ void set setter14(S Function<S extends T>(S) value) {}
+ void set setter15(void Function(S Function<S extends T>()) value) {}
+ void set setter2(T Function() value) {}
+ void set setter3(void Function(T) value) {}
+ void set setter4(T Function(T) value) {}
+ void set setter5(T Function() Function() value) {}
+ void set setter6(void Function(T Function()) value) {}
+ void set setter7(T Function(T Function()) value) {}
+ void set setter8(void Function(void Function(T)) value) {}
+ void set setter9(T Function(void Function(T)) value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/null_aware.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware.dart.textual_outline.expect
new file mode 100644
index 0000000..bafe8cc
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+class Foo {
+ int field;
+ static int staticField;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/null_aware.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bafe8cc
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+class Foo {
+ int field;
+ static int staticField;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_for_in.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_for_in.dart.textual_outline.expect
new file mode 100644
index 0000000..43e0a72
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_for_in.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+class Class {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_for_in.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_for_in.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..43e0a72
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_for_in.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+class Class {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_postfix.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_postfix.dart.textual_outline.expect
new file mode 100644
index 0000000..7fa7e53
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_postfix.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+// @dart = 2.6
+class A {
+ B b;
+}
+
+class B {
+ C operator +(int i) => null;
+}
+
+class C extends B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_postfix.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_postfix.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7fa7e53
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_postfix.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+// @dart = 2.6
+class A {
+ B b;
+}
+
+class B {
+ C operator +(int i) => null;
+}
+
+class C extends B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_spread.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_spread.dart.textual_outline.expect
new file mode 100644
index 0000000..5e023d7
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_spread.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+nullAwareListSpread(List<String> list) {}
+nullAwareSetSpread(Set<String> set) {}
+nullAwareMapSpread(Map<int, String> map) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_spread.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_spread.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..20bd984
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/null_aware_spread.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+main() {}
+nullAwareListSpread(List<String> list) {}
+nullAwareMapSpread(Map<int, String> map) {}
+nullAwareSetSpread(Set<String> set) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/operator_method_not_found.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/operator_method_not_found.dart.textual_outline.expect
new file mode 100644
index 0000000..1a0868f
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/operator_method_not_found.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+class Foo {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/operator_method_not_found.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/operator_method_not_found.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1a0868f
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/operator_method_not_found.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+class Foo {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/operators.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/operators.dart.textual_outline.expect
new file mode 100644
index 0000000..481687e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/operators.dart.textual_outline.expect
@@ -0,0 +1,25 @@
+// @dart = 2.6
+class Operators {
+ operator +(other) => null;
+ operator &(other) => null;
+ operator ~() => null;
+ operator |(other) => null;
+ operator ^(other) => null;
+ operator /(other) => null;
+ operator ==(other) => null;
+ operator >(other) => null;
+ operator >=(other) => null;
+ operator [](index) => null;
+ void operator []=(index, value) {}
+ operator <<(other) => null;
+ operator <(other) => null;
+ operator <=(other) => null;
+ operator *(other) => null;
+ operator %(other) => null;
+ operator >>(other) => null;
+ operator -(other) => null;
+ operator ~/(other) => null;
+ operator -() => null;
+}
+
+main(arguments) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/operators.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/operators.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..078d711
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/operators.dart.textual_outline_modelled.expect
@@ -0,0 +1,25 @@
+// @dart = 2.6
+class Operators {
+ operator %(other) => null;
+ operator &(other) => null;
+ operator *(other) => null;
+ operator +(other) => null;
+ operator -() => null;
+ operator -(other) => null;
+ operator /(other) => null;
+ operator <(other) => null;
+ operator <<(other) => null;
+ operator <=(other) => null;
+ operator ==(other) => null;
+ operator >(other) => null;
+ operator >=(other) => null;
+ operator >>(other) => null;
+ operator [](index) => null;
+ operator ^(other) => null;
+ operator |(other) => null;
+ operator ~() => null;
+ operator ~/(other) => null;
+ void operator []=(index, value) {}
+}
+
+main(arguments) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/optional.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/optional.dart.textual_outline.expect
new file mode 100644
index 0000000..fefc2ed
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/optional.dart.textual_outline.expect
@@ -0,0 +1,29 @@
+// @dart = 2.6
+class Foo {
+ method(x, [y, z]) {}
+}
+
+abstract class External {
+ String externalMethod(int x, [int y, int z]);
+ void listen(Listener listener);
+}
+
+external External createExternal();
+
+abstract class Listener {
+ void event(String input, [int x, int y]);
+}
+
+class TestListener extends Listener {
+ void event(input, [x, y]) {}
+}
+
+class ExtendedListener extends Listener {
+ void event(input, [x, y, z]) {}
+}
+
+class InvalidListener {
+ void event(input, [x]) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/optional.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/optional.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..686656a
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/optional.dart.textual_outline_modelled.expect
@@ -0,0 +1,28 @@
+// @dart = 2.6
+abstract class External {
+ String externalMethod(int x, [int y, int z]);
+ void listen(Listener listener);
+}
+
+abstract class Listener {
+ void event(String input, [int x, int y]);
+}
+
+class ExtendedListener extends Listener {
+ void event(input, [x, y, z]) {}
+}
+
+class Foo {
+ method(x, [y, z]) {}
+}
+
+class InvalidListener {
+ void event(input, [x]) {}
+}
+
+class TestListener extends Listener {
+ void event(input, [x, y]) {}
+}
+
+external External createExternal();
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override.dart.textual_outline.expect
new file mode 100644
index 0000000..bd802d4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+class Foo {}
+
+class Bar extends Foo {}
+
+class Base {
+ Foo method() {}
+}
+
+class Sub extends Base {
+ Foo method() {}
+}
+
+main(List<String> args) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..857d43d
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+class Bar extends Foo {}
+
+class Base {
+ Foo method() {}
+}
+
+class Foo {}
+
+class Sub extends Base {
+ Foo method() {}
+}
+
+main(List<String> args) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_check_accessor_after_inference.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_accessor_after_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..e0a4d3b
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_accessor_after_inference.dart.textual_outline.expect
@@ -0,0 +1,26 @@
+// @dart = 2.6
+class A {}
+
+class B extends A {}
+
+class C {
+ void set x(A value) {}
+ B get y => null;
+}
+
+class D extends C {
+ void set x(value) {}
+ get y => null;
+}
+
+class E extends D {
+ void set x(A value) {}
+ B get y => null;
+}
+
+class F extends D {
+ void set x(B value) {}
+ A get y => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_check_accessor_after_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_accessor_after_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f5cef13
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_accessor_after_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,26 @@
+// @dart = 2.6
+class A {}
+
+class B extends A {}
+
+class C {
+ B get y => null;
+ void set x(A value) {}
+}
+
+class D extends C {
+ get y => null;
+ void set x(value) {}
+}
+
+class E extends D {
+ B get y => null;
+ void set x(A value) {}
+}
+
+class F extends D {
+ A get y => null;
+ void set x(B value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_check_accessor_basic.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_accessor_basic.dart.textual_outline.expect
new file mode 100644
index 0000000..2eac781
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_accessor_basic.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+// @dart = 2.6
+class A {}
+
+class B extends A {}
+
+class C {
+ void set x(A value) {}
+ A get y => null;
+}
+
+class D extends C {
+ void set x(Object value) {}
+ B get y => null;
+}
+
+class E extends C {
+ void set x(B value) {}
+ Object get y => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_check_accessor_basic.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_accessor_basic.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..434390e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_accessor_basic.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+// @dart = 2.6
+class A {}
+
+class B extends A {}
+
+class C {
+ A get y => null;
+ void set x(A value) {}
+}
+
+class D extends C {
+ B get y => null;
+ void set x(Object value) {}
+}
+
+class E extends C {
+ Object get y => null;
+ void set x(B value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_check_accessor_with_covariant_modifier.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_accessor_with_covariant_modifier.dart.textual_outline.expect
new file mode 100644
index 0000000..37a5988
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_accessor_with_covariant_modifier.dart.textual_outline.expect
@@ -0,0 +1,24 @@
+// @dart = 2.6
+class A {}
+
+class B extends A {}
+
+class C {
+ void set x1(covariant A value) {}
+ void set x2(A value) {}
+ void set x3(covariant A value) {}
+ void set x4(A value) {}
+ void set x5(covariant A value) {}
+ void set x6(covariant B value) {}
+}
+
+class D extends C {
+ void set x1(B value) {}
+ void set x2(covariant B value) {}
+ void set x3(covariant B value) {}
+ void set x4(B value) {}
+ void set x5(covariant String value) {}
+ void set x6(covariant A value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_check_accessor_with_covariant_modifier.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_accessor_with_covariant_modifier.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..37a5988
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_accessor_with_covariant_modifier.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+// @dart = 2.6
+class A {}
+
+class B extends A {}
+
+class C {
+ void set x1(covariant A value) {}
+ void set x2(A value) {}
+ void set x3(covariant A value) {}
+ void set x4(A value) {}
+ void set x5(covariant A value) {}
+ void set x6(covariant B value) {}
+}
+
+class D extends C {
+ void set x1(B value) {}
+ void set x2(covariant B value) {}
+ void set x3(covariant B value) {}
+ void set x4(B value) {}
+ void set x5(covariant String value) {}
+ void set x6(covariant A value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_check_after_inference.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_after_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..27efff1
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_after_inference.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+// @dart = 2.6
+class A {}
+
+class B extends A {}
+
+class C {
+ void f(A x) {}
+}
+
+class D extends C {
+ void f(x) {}
+}
+
+class E extends D {
+ void f(A x) {}
+}
+
+class F extends D {
+ void f(B x) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_check_after_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_after_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..27efff1
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_after_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,22 @@
+// @dart = 2.6
+class A {}
+
+class B extends A {}
+
+class C {
+ void f(A x) {}
+}
+
+class D extends C {
+ void f(x) {}
+}
+
+class E extends D {
+ void f(A x) {}
+}
+
+class F extends D {
+ void f(B x) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_check_basic.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_basic.dart.textual_outline.expect
new file mode 100644
index 0000000..16702e3
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_basic.dart.textual_outline.expect
@@ -0,0 +1,27 @@
+// @dart = 2.6
+class A {}
+
+class B extends A {}
+
+class C {
+ void f1(A x) {}
+ void f2([A x]) {}
+ void f3({A x}) {}
+ A f4() {}
+}
+
+class D extends C {
+ void f1(Object x) {}
+ void f2([Object x]) {}
+ void f3({Object x}) {}
+ B f4() {}
+}
+
+class E extends C {
+ void f1(B x) {}
+ void f2([B x]) {}
+ void f3({B x}) {}
+ Object f4() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_check_basic.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_basic.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6ae09bf
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_basic.dart.textual_outline_modelled.expect
@@ -0,0 +1,27 @@
+// @dart = 2.6
+class A {}
+
+class B extends A {}
+
+class C {
+ A f4() {}
+ void f1(A x) {}
+ void f2([A x]) {}
+ void f3({A x}) {}
+}
+
+class D extends C {
+ B f4() {}
+ void f1(Object x) {}
+ void f2([Object x]) {}
+ void f3({Object x}) {}
+}
+
+class E extends C {
+ Object f4() {}
+ void f1(B x) {}
+ void f2([B x]) {}
+ void f3({B x}) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_check_generic_method_f_bounded.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_generic_method_f_bounded.dart.textual_outline.expect
new file mode 100644
index 0000000..4f5df34
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_generic_method_f_bounded.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+// @dart = 2.6
+class Foo<T extends Foo<T>> {}
+
+abstract class Bar {
+ void fisk<S extends Foo<S>>();
+}
+
+class Hest implements Bar {
+ @override
+ void fisk<U extends Foo<U>>() {}
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_check_generic_method_f_bounded.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_generic_method_f_bounded.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6832671
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_generic_method_f_bounded.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+// @dart = 2.6
+abstract class Bar {
+ void fisk<S extends Foo<S>>();
+}
+
+class Foo<T extends Foo<T>> {}
+
+class Hest implements Bar {
+ @override
+ void fisk<U extends Foo<U>>() {}
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_check_two_substitutions.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_two_substitutions.dart.textual_outline.expect
new file mode 100644
index 0000000..bb679c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_two_substitutions.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+class A<T> {
+ void f<U>(Map<T, U> m) {}
+}
+
+class B extends A<String> {
+ void f<V>(Map<String, V> m) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_check_two_substitutions.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_two_substitutions.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bb679c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_two_substitutions.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+class A<T> {
+ void f<U>(Map<T, U> m) {}
+}
+
+class B extends A<String> {
+ void f<V>(Map<String, V> m) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_check_with_covariant_modifier.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_with_covariant_modifier.dart.textual_outline.expect
new file mode 100644
index 0000000..9a29d45
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_with_covariant_modifier.dart.textual_outline.expect
@@ -0,0 +1,24 @@
+// @dart = 2.6
+class A {}
+
+class B extends A {}
+
+class C {
+ void f1(covariant A x) {}
+ void f2(A x) {}
+ void f3(covariant A x) {}
+ void f4(A x) {}
+ void f5(covariant A x) {}
+ void f6(covariant B x) {}
+}
+
+class D extends C {
+ void f1(B x) {}
+ void f2(covariant B x) {}
+ void f3(covariant B x) {}
+ void f4(B x) {}
+ void f5(covariant String x) {}
+ void f6(covariant A x) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_check_with_covariant_modifier.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_with_covariant_modifier.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9a29d45
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_check_with_covariant_modifier.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+// @dart = 2.6
+class A {}
+
+class B extends A {}
+
+class C {
+ void f1(covariant A x) {}
+ void f2(A x) {}
+ void f3(covariant A x) {}
+ void f4(A x) {}
+ void f5(covariant A x) {}
+ void f6(covariant B x) {}
+}
+
+class D extends C {
+ void f1(B x) {}
+ void f2(covariant B x) {}
+ void f3(covariant B x) {}
+ void f4(B x) {}
+ void f5(covariant String x) {}
+ void f6(covariant A x) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_inference_for_setters.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_inference_for_setters.dart.textual_outline.expect
new file mode 100644
index 0000000..405d608
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_inference_for_setters.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+// @dart = 2.6
+class B {
+ num get foo => null;
+ set foo(dynamic newFoo) {}
+}
+
+class A extends B {
+ set foo(newFoo) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_inference_for_setters.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_inference_for_setters.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..aded191
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_inference_for_setters.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+// @dart = 2.6
+class A extends B {
+ set foo(newFoo) {}
+}
+
+class B {
+ num get foo => null;
+ set foo(dynamic newFoo) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_inference_named_parameters_ordering.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_inference_named_parameters_ordering.dart.textual_outline.expect
new file mode 100644
index 0000000..c56c48e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_inference_named_parameters_ordering.dart.textual_outline.expect
@@ -0,0 +1,26 @@
+// @dart = 2.6
+class A {
+ foo({bool c = true, bool a}) {}
+}
+
+class B extends A {
+ foo({c = true, bool a}) {}
+}
+
+class C extends B {
+ foo({bool c = true, bool a}) {}
+}
+
+class A1 {
+ foo({bool a = true, bool c}) {}
+}
+
+class B1 extends A1 {
+ foo({a = true, bool c}) {}
+}
+
+class C1 extends B1 {
+ foo({bool a = true, bool c}) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_inference_named_parameters_ordering.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_inference_named_parameters_ordering.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cd5ed60e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_inference_named_parameters_ordering.dart.textual_outline_modelled.expect
@@ -0,0 +1,26 @@
+// @dart = 2.6
+class A {
+ foo({bool c = true, bool a}) {}
+}
+
+class A1 {
+ foo({bool a = true, bool c}) {}
+}
+
+class B extends A {
+ foo({c = true, bool a}) {}
+}
+
+class B1 extends A1 {
+ foo({a = true, bool c}) {}
+}
+
+class C extends B {
+ foo({bool c = true, bool a}) {}
+}
+
+class C1 extends B1 {
+ foo({bool a = true, bool c}) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_setter_with_field.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_setter_with_field.dart.textual_outline.expect
new file mode 100644
index 0000000..efb031f
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_setter_with_field.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+abstract class A {
+ void set x(Object y);
+}
+
+class B implements A {
+ int x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/override_setter_with_field.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/override_setter_with_field.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..efb031f
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/override_setter_with_field.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+abstract class A {
+ void set x(Object y);
+}
+
+class B implements A {
+ int x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/part_as_entry_point.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/part_as_entry_point.dart.textual_outline.expect
new file mode 100644
index 0000000..56c5193
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/part_as_entry_point.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+part of "part_as_entry_point_lib.dart";
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/part_as_entry_point.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/part_as_entry_point.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..56c5193
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/part_as_entry_point.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+part of "part_as_entry_point_lib.dart";
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/part_not_part_of.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/part_not_part_of.dart.textual_outline.expect
new file mode 100644
index 0000000..49e7a9f
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/part_not_part_of.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'part_not_part_of_lib2.dart';
+@override
+part 'part_not_part_of_lib1.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/part_not_part_of.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/part_not_part_of.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..49e7a9f
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/part_not_part_of.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'part_not_part_of_lib2.dart';
+@override
+part 'part_not_part_of_lib1.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/part_not_part_of_same_named_library.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/part_not_part_of_same_named_library.dart.textual_outline.expect
new file mode 100644
index 0000000..5094fa1
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/part_not_part_of_same_named_library.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'part_not_part_of_same_named_library_lib2.dart';
+@override
+part 'part_not_part_of_same_named_library_lib1.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/part_not_part_of_same_named_library.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/part_not_part_of_same_named_library.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5094fa1
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/part_not_part_of_same_named_library.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'part_not_part_of_same_named_library_lib2.dart';
+@override
+part 'part_not_part_of_same_named_library_lib1.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/part_part_of_different_unnamed_library.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/part_part_of_different_unnamed_library.dart.textual_outline.expect
new file mode 100644
index 0000000..24b780d
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/part_part_of_different_unnamed_library.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'part_part_of_different_unnamed_library_lib2.dart';
+@override
+part 'part_part_of_different_unnamed_library_lib1.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/part_part_of_different_unnamed_library.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/part_part_of_different_unnamed_library.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..24b780d
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/part_part_of_different_unnamed_library.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'part_part_of_different_unnamed_library_lib2.dart';
+@override
+part 'part_part_of_different_unnamed_library_lib1.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/part_part_of_differently_named_library.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/part_part_of_differently_named_library.dart.textual_outline.expect
new file mode 100644
index 0000000..ea5cdd5
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/part_part_of_differently_named_library.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+library foo;
+
+import 'part_part_of_differently_named_library_lib2.dart';
+@override
+part 'part_part_of_differently_named_library_lib1.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/part_part_of_differently_named_library.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/part_part_of_differently_named_library.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ea5cdd5
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/part_part_of_differently_named_library.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+library foo;
+
+import 'part_part_of_differently_named_library_lib2.dart';
+@override
+part 'part_part_of_differently_named_library_lib1.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/platform.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/platform.dart.textual_outline.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/platform.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/platform.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/platform.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..506b9c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/platform.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+// @dart = 2.6
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/prefer_baseclass.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/prefer_baseclass.dart.textual_outline.expect
new file mode 100644
index 0000000..f124a27
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/prefer_baseclass.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+// @dart = 2.6
+class A {}
+
+class B {}
+
+class AB1 extends A implements B {}
+
+class AB2 extends A implements B {}
+
+class BA1 extends B implements A {}
+
+class BA2 extends B implements A {}
+
+takeSubclassOfA(obj) {}
+takeSubclassOfB(obj) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/prefer_baseclass.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/prefer_baseclass.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..615035f
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/prefer_baseclass.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+// @dart = 2.6
+class A {}
+
+class AB1 extends A implements B {}
+
+class AB2 extends A implements B {}
+
+class B {}
+
+class BA1 extends B implements A {}
+
+class BA2 extends B implements A {}
+
+main() {}
+takeSubclassOfA(obj) {}
+takeSubclassOfB(obj) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/private_method_tearoff.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/private_method_tearoff.dart.textual_outline.expect
new file mode 100644
index 0000000..d709d38
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/private_method_tearoff.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+import './private_method_tearoff_lib.dart';
+
+class Foo implements Bar {}
+
+class Baz extends Foo {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/private_method_tearoff.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/private_method_tearoff.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5d346af
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/private_method_tearoff.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+import './private_method_tearoff_lib.dart';
+
+class Baz extends Foo {}
+
+class Foo implements Bar {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/promoted_access.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/promoted_access.dart.textual_outline.expect
new file mode 100644
index 0000000..4e30433
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/promoted_access.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+class Class<T> {
+ method(T o) {}
+}
+
+method<T>(T o) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/promoted_access.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/promoted_access.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6e6741a
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/promoted_access.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+class Class<T> {
+ method(T o) {}
+}
+
+main() {}
+method<T>(T o) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/public_method_tearoff.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/public_method_tearoff.dart.textual_outline.expect
new file mode 100644
index 0000000..c43b7fd
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/public_method_tearoff.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import './public_method_tearoff_lib.dart';
+
+class Foo extends Bar {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/public_method_tearoff.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/public_method_tearoff.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c43b7fd
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/public_method_tearoff.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import './public_method_tearoff_lib.dart';
+
+class Foo extends Bar {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/qualified.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/qualified.dart.textual_outline.expect
new file mode 100644
index 0000000..437d273
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/qualified.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+// @dart = 2.6
+library test.qualified.main;
+
+import "qualified_lib.dart" as lib;
+part "qualified_part.dart";
+
+class Bad extends lib.Missing {
+ lib.Missing method() {}
+ factory WrongName() {}
+}
+
+class WithMixin extends lib.Supertype with lib.Mixin {}
+
+class IllegalSupertype extends lib.VoidFunction {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/qualified.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/qualified.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4102d33
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/qualified.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+// @dart = 2.6
+library test.qualified.main;
+
+import "qualified_lib.dart" as lib;
+part "qualified_part.dart";
+
+class Bad extends lib.Missing {
+ factory WrongName() {}
+ lib.Missing method() {}
+}
+
+class IllegalSupertype extends lib.VoidFunction {}
+
+class WithMixin extends lib.Supertype with lib.Mixin {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_constructor.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_constructor.dart.textual_outline.expect
new file mode 100644
index 0000000..470f695
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_constructor.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+class A {
+ A();
+ factory A.fisk() = B;
+}
+
+class B extends A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_constructor.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_constructor.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..470f695
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_constructor.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+class A {
+ A();
+ factory A.fisk() = B;
+}
+
+class B extends A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory.dart.textual_outline.expect
new file mode 100644
index 0000000..7efd803
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory.dart.textual_outline.expect
@@ -0,0 +1,35 @@
+// @dart = 2.6
+abstract class FooBase<Tf> {
+ int get x;
+ factory FooBase(int x) = Foo<Tf>;
+}
+
+abstract class Foo<T> implements FooBase {
+ factory Foo(int x) = Bar<String, T>;
+}
+
+class Bar<Sb, Tb> implements Foo<Tb> {
+ int x;
+ Bar(this.x) {}
+}
+
+class Builder<X> {
+ method() {}
+}
+
+class SimpleCase<A, B> {
+ factory SimpleCase() = SimpleCaseImpl<A, B>;
+}
+
+class SimpleCaseImpl<Ai, Bi> implements SimpleCase<Ai, Bi> {
+ factory SimpleCaseImpl() = SimpleCaseImpl2<Ai, Bi>;
+}
+
+class SimpleCaseImpl2<Ai2, Bi2> implements SimpleCaseImpl<Ai2, Bi2> {}
+
+class Base<M> {}
+
+class Mixin<M> {}
+
+class Mix<M> = Base<M> with Mixin<M>;
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..43e7c92
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory.dart.textual_outline_modelled.expect
@@ -0,0 +1,35 @@
+// @dart = 2.6
+abstract class Foo<T> implements FooBase {
+ factory Foo(int x) = Bar<String, T>;
+}
+
+abstract class FooBase<Tf> {
+ factory FooBase(int x) = Foo<Tf>;
+ int get x;
+}
+
+class Bar<Sb, Tb> implements Foo<Tb> {
+ Bar(this.x) {}
+ int x;
+}
+
+class Base<M> {}
+
+class Builder<X> {
+ method() {}
+}
+
+class Mixin<M> {}
+
+class SimpleCase<A, B> {
+ factory SimpleCase() = SimpleCaseImpl<A, B>;
+}
+
+class SimpleCaseImpl2<Ai2, Bi2> implements SimpleCaseImpl<Ai2, Bi2> {}
+
+class SimpleCaseImpl<Ai, Bi> implements SimpleCase<Ai, Bi> {
+ factory SimpleCaseImpl() = SimpleCaseImpl2<Ai, Bi>;
+}
+
+class Mix<M> = Base<M> with Mixin<M>;
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_chain_test.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_chain_test.dart.textual_outline.expect
new file mode 100644
index 0000000..25a1082
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_chain_test.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+library redirecting_factory_constructors.chain_test;
+
+class A {
+ A();
+ factory A.first() = A;
+ factory A.second() = A.first;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_chain_test.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_chain_test.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..25a1082
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_chain_test.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+library redirecting_factory_constructors.chain_test;
+
+class A {
+ A();
+ factory A.first() = A;
+ factory A.second() = A.first;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_const_inference.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_const_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..4767533
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_const_inference.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+// @dart = 2.6
+class _X<T> {
+ const factory _X() = _Y<T>;
+}
+
+class _Y<T> implements _X<T> {
+ const _Y();
+}
+
+class A<T> {
+ _X<T> x;
+ A(this.x);
+}
+
+class B<T> extends A<T> {
+ B() : super(const _X());
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_const_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_const_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..889323b
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_const_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+// @dart = 2.6
+class A<T> {
+ A(this.x);
+ _X<T> x;
+}
+
+class B<T> extends A<T> {
+ B() : super(const _X());
+}
+
+class _X<T> {
+ const factory _X() = _Y<T>;
+}
+
+class _Y<T> implements _X<T> {
+ const _Y();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_metadata.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_metadata.dart.textual_outline.expect
new file mode 100644
index 0000000..1a59844
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_metadata.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+// @dart = 2.6
+const forParameter = 1;
+const forFactoryItself = 2;
+const anotherForParameter = 3;
+
+class Foo {
+ @forFactoryItself
+ factory Foo(@forParameter @anotherForParameter p) = Foo.named;
+ Foo.named(p);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_metadata.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_metadata.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..465cd5b
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_metadata.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+// @dart = 2.6
+class Foo {
+ @forFactoryItself
+ factory Foo(@forParameter @anotherForParameter p) = Foo.named;
+ Foo.named(p);
+}
+
+const anotherForParameter = 3;
+const forFactoryItself = 2;
+const forParameter = 1;
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_simple_test.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_simple_test.dart.textual_outline.expect
new file mode 100644
index 0000000..72e8dd1
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_simple_test.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+library redirecting_factory_constructors.simple_test;
+
+class A {
+ A();
+ factory A.redir() = A;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_simple_test.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_simple_test.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..72e8dd1
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_simple_test.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+library redirecting_factory_constructors.simple_test;
+
+class A {
+ A();
+ factory A.redir() = A;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_typeargs_test.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_typeargs_test.dart.textual_outline.expect
new file mode 100644
index 0000000..e6e9dba
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_typeargs_test.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+// @dart = 2.6
+library redirecting_factory_constructors.typeargs_test;
+
+class X {}
+
+class Y extends X {}
+
+class A {
+ A();
+ factory A.redir() = B<Y>;
+}
+
+class B<T extends X> extends A {
+ B();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_typeargs_test.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_typeargs_test.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0bc43b3
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_typeargs_test.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+// @dart = 2.6
+library redirecting_factory_constructors.typeargs_test;
+
+class A {
+ A();
+ factory A.redir() = B<Y>;
+}
+
+class B<T extends X> extends A {
+ B();
+}
+
+class X {}
+
+class Y extends X {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_typeparam_test.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_typeparam_test.dart.textual_outline.expect
new file mode 100644
index 0000000..06f0190
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_typeparam_test.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+library redirecting_factory_constructors.typeparam_test;
+
+class A<T, S> {
+ A(T t, S s);
+ factory A.redir(T t, S s) = A<T, S>;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_typeparam_test.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_typeparam_test.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..06f0190
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_typeparam_test.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+library redirecting_factory_constructors.typeparam_test;
+
+class A<T, S> {
+ A(T t, S s);
+ factory A.redir(T t, S s) = A<T, S>;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_typeparambounds_test.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_typeparambounds_test.dart.textual_outline.expect
new file mode 100644
index 0000000..80e15be
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_typeparambounds_test.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+// @dart = 2.6
+library redirecting_factory_constructors.typeparambounds_test;
+
+class X {}
+
+class Y extends X {}
+
+class A<T, S extends T> {
+ A(T t, S s);
+ factory A.redir(T t, S s) = A<T, S>;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_typeparambounds_test.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_typeparambounds_test.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7d63864
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_factory_typeparambounds_test.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+// @dart = 2.6
+library redirecting_factory_constructors.typeparambounds_test;
+
+class A<T, S extends T> {
+ A(T t, S s);
+ factory A.redir(T t, S s) = A<T, S>;
+}
+
+class X {}
+
+class Y extends X {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_initializer_arguments_assignable_test.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_initializer_arguments_assignable_test.dart.textual_outline.expect
new file mode 100644
index 0000000..1473d4d
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_initializer_arguments_assignable_test.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+// @dart = 2.6
+class X {}
+
+class Foo<T extends X> {
+ T x;
+ Foo.fromX(X _init) : this._internal(x: _init);
+ Foo.fromT(T _init) : this._internal(x: _init);
+ Foo._internal({this.x});
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_initializer_arguments_assignable_test.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_initializer_arguments_assignable_test.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6cc8c23
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_initializer_arguments_assignable_test.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+// @dart = 2.6
+class Foo<T extends X> {
+ Foo._internal({this.x});
+ Foo.fromT(T _init) : this._internal(x: _init);
+ Foo.fromX(X _init) : this._internal(x: _init);
+ T x;
+}
+
+class X {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_initializer_arguments_test.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_initializer_arguments_test.dart.textual_outline.expect
new file mode 100644
index 0000000..ee6bdf0
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_initializer_arguments_test.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+class Foo<T> {
+ T x;
+ Foo.from(String _init) : this._internal(x: _init);
+ Foo._internal({this.x});
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_initializer_arguments_test.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_initializer_arguments_test.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..987d68d
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirecting_initializer_arguments_test.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+class Foo<T> {
+ Foo._internal({this.x});
+ Foo.from(String _init) : this._internal(x: _init);
+ T x;
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirection_chain_type_arguments.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirection_chain_type_arguments.dart.textual_outline.expect
new file mode 100644
index 0000000..1f7d067
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirection_chain_type_arguments.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+// @dart = 2.6
+import 'package:expect/expect.dart';
+
+class A<T> {
+ factory A() = B<T, num>;
+ A.empty();
+}
+
+class B<U, W> extends A<U> {
+ factory B() = C<U, W, String>;
+ B.empty() : super.empty();
+}
+
+class C<V, S, R> extends B<V, S> {
+ C() : super.empty();
+ toString() => "${V},${S},${R}";
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirection_chain_type_arguments.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirection_chain_type_arguments.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ebbc0f2
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirection_chain_type_arguments.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+// @dart = 2.6
+import 'package:expect/expect.dart';
+
+class A<T> {
+ A.empty();
+ factory A() = B<T, num>;
+}
+
+class B<U, W> extends A<U> {
+ B.empty() : super.empty();
+ factory B() = C<U, W, String>;
+}
+
+class C<V, S, R> extends B<V, S> {
+ C() : super.empty();
+ toString() => "${V},${S},${R}";
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirection_chain_type_arguments_subst.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirection_chain_type_arguments_subst.dart.textual_outline.expect
new file mode 100644
index 0000000..ccc7cc7
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirection_chain_type_arguments_subst.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+// @dart = 2.6
+import 'package:expect/expect.dart';
+
+abstract class A<T> {
+ factory A() = B<T, List<T>>;
+ A.empty();
+}
+
+abstract class B<U, W> extends A<U> {
+ factory B() = C<U, W, Map<U, W>>;
+ B.empty() : super.empty();
+}
+
+class C<V, S, R> extends B<V, S> {
+ C() : super.empty();
+ toString() => "${V},${S},${R}";
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirection_chain_type_arguments_subst.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirection_chain_type_arguments_subst.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..60429ec
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirection_chain_type_arguments_subst.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+// @dart = 2.6
+import 'package:expect/expect.dart';
+
+abstract class A<T> {
+ A.empty();
+ factory A() = B<T, List<T>>;
+}
+
+abstract class B<U, W> extends A<U> {
+ B.empty() : super.empty();
+ factory B() = C<U, W, Map<U, W>>;
+}
+
+class C<V, S, R> extends B<V, S> {
+ C() : super.empty();
+ toString() => "${V},${S},${R}";
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirection_type_arguments.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirection_type_arguments.dart.textual_outline.expect
new file mode 100644
index 0000000..6394a90
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirection_type_arguments.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+import 'package:expect/expect.dart';
+
+class A {
+ const factory A() = B<String>;
+ const A.empty();
+}
+
+class B<T> extends A {
+ const B() : super.empty();
+ toString() => '${T}';
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/redirection_type_arguments.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/redirection_type_arguments.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bc1e553
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/redirection_type_arguments.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+import 'package:expect/expect.dart';
+
+class A {
+ const A.empty();
+ const factory A() = B<String>;
+}
+
+class B<T> extends A {
+ const B() : super.empty();
+ toString() => '${T}';
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/reject_generic_function_types_in_bounds.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/reject_generic_function_types_in_bounds.dart.textual_outline.expect
new file mode 100644
index 0000000..72477c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/reject_generic_function_types_in_bounds.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+class Hest<TypeX extends TypeY Function<TypeY>(TypeY)> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/reject_generic_function_types_in_bounds.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/reject_generic_function_types_in_bounds.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..72477c4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/reject_generic_function_types_in_bounds.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+class Hest<TypeX extends TypeY Function<TypeY>(TypeY)> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/return_with_unknown_type_in_context.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/return_with_unknown_type_in_context.dart.textual_outline.expect
new file mode 100644
index 0000000..fcffd7e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/return_with_unknown_type_in_context.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+bool f(List x) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/return_with_unknown_type_in_context.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/return_with_unknown_type_in_context.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fcffd7e
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/return_with_unknown_type_in_context.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+bool f(List x) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart.textual_outline.expect
new file mode 100644
index 0000000..2c7d4ce
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+class C extends Iterable<Object> {}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9771aa3
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/sdk_diagnostic.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+class C extends Iterable<Object> {}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection.dart.textual_outline.expect
new file mode 100644
index 0000000..f5f9183
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+main() {}
+foo() => null;
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e69d5d9
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+foo() => null;
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..aea5ba4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+Map<K, V> bar<K, V>() => null;
+foo(dynamic dynVar) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..aea5ba4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/spread_collection_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+Map<K, V> bar<K, V>() => null;
+foo(dynamic dynVar) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/statements.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/statements.dart.textual_outline.expect
new file mode 100644
index 0000000..43f51e0
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/statements.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+foo() {}
+bar() async {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/statements.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/statements.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8532037
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/statements.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+bar() async {}
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/static_setter.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/static_setter.dart.textual_outline.expect
new file mode 100644
index 0000000..8d98297
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/static_setter.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+class Foo {}
+
+set foo(x) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/static_setter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/static_setter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..42cccc3
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/static_setter.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+class Foo {}
+
+main() {}
+set foo(x) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/store_load.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/store_load.dart.textual_outline.expect
new file mode 100644
index 0000000..1ecc972
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/store_load.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+class Foo {
+ var _field;
+}
+
+class FooValue {}
+
+class Bar {
+ var _field;
+}
+
+class BarValue {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/store_load.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/store_load.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fe6cd34
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/store_load.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+class Bar {
+ var _field;
+}
+
+class BarValue {}
+
+class Foo {
+ var _field;
+}
+
+class FooValue {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/stringliteral.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/stringliteral.dart.textual_outline.expect
new file mode 100644
index 0000000..e79dab7
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/stringliteral.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+var color = 'brown';
+var thing = 'lazy dog';
+var phrase = "The quick $color fox\njumped over the $thing.\n";
+var adjacent = '$color$color$color';
+var linebreaks = '$color\n$color\n$color';
+var other = '$color\n is \n$color';
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/stringliteral.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/stringliteral.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..dc991f6
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/stringliteral.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+main() {}
+var adjacent = '$color$color$color';
+var color = 'brown';
+var linebreaks = '$color\n$color\n$color';
+var other = '$color\n is \n$color';
+var phrase = "The quick $color fox\njumped over the $thing.\n";
+var thing = 'lazy dog';
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/super_call.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/super_call.dart.textual_outline.expect
new file mode 100644
index 0000000..25ae6c7
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/super_call.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+// @dart = 2.6
+class A {
+ int call(int x) => x * 2;
+}
+
+class B extends A {
+ int call(int x) => x * 3;
+ int call_super() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/super_call.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/super_call.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..25ae6c7
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/super_call.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+// @dart = 2.6
+class A {
+ int call(int x) => x * 2;
+}
+
+class B extends A {
+ int call(int x) => x * 3;
+ int call_super() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/super_nsm.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/super_nsm.dart.textual_outline.expect
new file mode 100644
index 0000000..6f8142a
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/super_nsm.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+// @dart = 2.6
+abstract class I {
+ interfaceMethod();
+}
+
+class C implements I {
+ noSuchMethod(_) => "C";
+}
+
+class D extends C {
+ noSuchMethod(_) => "D";
+ dMethod() => super.interfaceMethod();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/super_nsm.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/super_nsm.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9e8ad96
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/super_nsm.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+// @dart = 2.6
+abstract class I {
+ interfaceMethod();
+}
+
+class C implements I {
+ noSuchMethod(_) => "C";
+}
+
+class D extends C {
+ dMethod() => super.interfaceMethod();
+ noSuchMethod(_) => "D";
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/tabs.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/tabs.dart.textual_outline.expect
new file mode 100644
index 0000000..5cf5db8
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/tabs.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/tabs.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/tabs.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..94295cd
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/tabs.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/three_typedefs_loop.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/three_typedefs_loop.dart.textual_outline.expect
new file mode 100644
index 0000000..8c08006
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/three_typedefs_loop.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+typedef Foo<T> = void Function(Bar<T>);
+typedef Bar<T> = void Function(Baz<T>);
+typedef Baz<T> = void Function(Foo<T>);
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/three_typedefs_loop.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/three_typedefs_loop.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6beff18
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/three_typedefs_loop.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+main() {}
+typedef Bar<T> = void Function(Baz<T>);
+typedef Baz<T> = void Function(Foo<T>);
+typedef Foo<T> = void Function(Bar<T>);
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/top_level_accessors.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/top_level_accessors.dart.textual_outline.expect
new file mode 100644
index 0000000..14ca2ae
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/top_level_accessors.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+library top_level_accessors;
+
+part 'top_level_accessors_part.dart';
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/top_level_accessors.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/top_level_accessors.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..14ca2ae
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/top_level_accessors.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+// @dart = 2.6
+library top_level_accessors;
+
+part 'top_level_accessors_part.dart';
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/top_level_library_method.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/top_level_library_method.dart.textual_outline.expect
new file mode 100644
index 0000000..9a2faad
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/top_level_library_method.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+library() {}
+main() => library();
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/top_level_library_method.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/top_level_library_method.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9a2faad
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/top_level_library_method.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+// @dart = 2.6
+library() {}
+main() => library();
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/type_literal_as_metadata.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/type_literal_as_metadata.dart.textual_outline.expect
new file mode 100644
index 0000000..83562c7
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/type_literal_as_metadata.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+class A {
+ const A();
+}
+
+@A
+class B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/type_literal_as_metadata.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/type_literal_as_metadata.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ed301d3
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/type_literal_as_metadata.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+@A
+class B {}
+
+class A {
+ const A();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/type_of_null.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/type_of_null.dart.textual_outline.expect
new file mode 100644
index 0000000..312495f
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/type_of_null.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+T map<T>(T Function() f1, T Function() f2) {}
+id<T>(T t) => t;
+Null foo() => null;
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/type_of_null.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/type_of_null.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..444071f
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/type_of_null.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+Null foo() => null;
+T map<T>(T Function() f1, T Function() f2) {}
+id<T>(T t) => t;
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/type_parameter_type_named_int.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/type_parameter_type_named_int.dart.textual_outline.expect
new file mode 100644
index 0000000..0f82905
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/type_parameter_type_named_int.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+abstract class Foo<T> {
+ List<T> get list;
+ void setList<T>(List<T> value);
+}
+
+class Bar implements Foo<int> {
+ List<int> list;
+ void setList<int>(List<int> value) {}
+}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/type_parameter_type_named_int.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/type_parameter_type_named_int.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0f82905
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/type_parameter_type_named_int.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+abstract class Foo<T> {
+ List<T> get list;
+ void setList<T>(List<T> value);
+}
+
+class Bar implements Foo<int> {
+ List<int> list;
+ void setList<int>(List<int> value) {}
+}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_as_super.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_as_super.dart.textual_outline.expect
new file mode 100644
index 0000000..829888b
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_as_super.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+abstract class A<T> extends T {}
+
+abstract class B<T> extends T {
+ B();
+}
+
+class C<T> extends T {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_as_super.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_as_super.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..829888b
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_as_super.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+// @dart = 2.6
+abstract class A<T> extends T {}
+
+abstract class B<T> extends T {
+ B();
+}
+
+class C<T> extends T {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_bound_access.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_bound_access.dart.textual_outline.expect
new file mode 100644
index 0000000..60421d4
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_bound_access.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+// @dart = 2.6
+class DynamicClass<T extends dynamic, S extends T> {
+ T field1;
+ T field2;
+ DynamicClass(this.field1, this.field2);
+ method() => field1 * field2;
+}
+
+class NumClass<T extends num, S extends T> {
+ T field1;
+ S field2;
+ NumClass(this.field1, this.field2);
+ num method1() => field1 * field2;
+ num method2() => field1 + field2.length;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_bound_access.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_bound_access.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..65451d7
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_bound_access.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+// @dart = 2.6
+class DynamicClass<T extends dynamic, S extends T> {
+ DynamicClass(this.field1, this.field2);
+ T field1;
+ T field2;
+ method() => field1 * field2;
+}
+
+class NumClass<T extends num, S extends T> {
+ NumClass(this.field1, this.field2);
+ S field2;
+ T field1;
+ num method1() => field1 * field2;
+ num method2() => field1 + field2.length;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_prefix.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_prefix.dart.textual_outline.expect
new file mode 100644
index 0000000..8ce9e43
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_prefix.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+import "dart:core" as T;
+
+class C<T> {
+ T.String method() => "Hello, World!";
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_prefix.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_prefix.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8ce9e43
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_prefix.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+import "dart:core" as T;
+
+class C<T> {
+ T.String method() => "Hello, World!";
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_uses.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_uses.dart.textual_outline.expect
new file mode 100644
index 0000000..f26d098
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_uses.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+class C<T> {
+ const C();
+ static C<T> staticMethod() {}
+ C<T> instanceMethod() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_uses.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_uses.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..39e4742
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/type_variable_uses.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+class C<T> {
+ C<T> instanceMethod() {}
+ const C();
+ static C<T> staticMethod() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/typedef.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/typedef.dart.textual_outline.expect
new file mode 100644
index 0000000..3e2bcc6
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/typedef.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+typedef _NullaryFunction();
+typedef _UnaryFunction(args);
+typedef _BinaryFunction(args, message);
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/typedef.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/typedef.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6e9e640
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/typedef.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+main() {}
+typedef _BinaryFunction(args, message);
+typedef _NullaryFunction();
+typedef _UnaryFunction(args);
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/undefined.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/undefined.dart.textual_outline.expect
new file mode 100644
index 0000000..9fd10ce
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/undefined.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+class C {
+ var x;
+ void f() {}
+}
+
+void test(C c) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/undefined.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/undefined.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..646c90b
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/undefined.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+class C {
+ var x;
+ void f() {}
+}
+
+main() {}
+void test(C c) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/undefined_getter_in_compound_assignment.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/undefined_getter_in_compound_assignment.dart.textual_outline.expect
new file mode 100644
index 0000000..d78b4c8
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/undefined_getter_in_compound_assignment.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+class C {
+ void set x(value) {}
+}
+
+void test(C c) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/undefined_getter_in_compound_assignment.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/undefined_getter_in_compound_assignment.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e21b39a
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/undefined_getter_in_compound_assignment.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+// @dart = 2.6
+class C {
+ void set x(value) {}
+}
+
+main() {}
+void test(C c) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/uninitialized_fields.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/uninitialized_fields.dart.textual_outline.expect
new file mode 100644
index 0000000..ae51bee
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/uninitialized_fields.dart.textual_outline.expect
@@ -0,0 +1,25 @@
+// @dart = 2.6
+class Uninitialized {
+ int x;
+}
+
+class PartiallyInitialized {
+ int x;
+ PartiallyInitialized(this.x);
+ PartiallyInitialized.noInitializer();
+}
+
+class Initialized {
+ int x;
+ Initialized(this.x);
+}
+
+class Forwarding {
+ int x;
+ Forwarding.initialize(this.x);
+ Forwarding(int arg) : this.initialize(arg);
+}
+
+int uninitializedTopLevel;
+int initializedTopLevel = 4;
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/uninitialized_fields.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/uninitialized_fields.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7bd0081
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/uninitialized_fields.dart.textual_outline_modelled.expect
@@ -0,0 +1,25 @@
+// @dart = 2.6
+class Forwarding {
+ Forwarding(int arg) : this.initialize(arg);
+ Forwarding.initialize(this.x);
+ int x;
+}
+
+class Initialized {
+ Initialized(this.x);
+ int x;
+}
+
+class PartiallyInitialized {
+ PartiallyInitialized(this.x);
+ PartiallyInitialized.noInitializer();
+ int x;
+}
+
+class Uninitialized {
+ int x;
+}
+
+int initializedTopLevel = 4;
+int uninitializedTopLevel;
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/unsound_promotion.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/unsound_promotion.dart.textual_outline.expect
new file mode 100644
index 0000000..fe7b0e7
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/unsound_promotion.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+// @dart = 2.6
+class A {}
+
+class B {}
+
+class C extends B implements A {}
+
+List<A> list;
+List<T> g<T extends A>(T t) {}
+List<S> f<S>(S s) {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/unsound_promotion.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/unsound_promotion.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6664ade
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/unsound_promotion.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+// @dart = 2.6
+List<A> list;
+List<S> f<S>(S s) {}
+List<T> g<T extends A>(T t) {}
+
+class A {}
+
+class B {}
+
+class C extends B implements A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/unused_methods.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/unused_methods.dart.textual_outline.expect
new file mode 100644
index 0000000..5bbb73f
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/unused_methods.dart.textual_outline.expect
@@ -0,0 +1,37 @@
+// @dart = 2.6
+class UnusedClass {
+ UnusedClass() {}
+}
+
+abstract class UsedAsBaseClass {
+ void usedInSubclass() {}
+ void calledFromB() {}
+ void calledFromSubclass() {}
+}
+
+class UsedAsInterface {
+ void usedInSubclass() {}
+}
+
+class InstantiatedButMethodsUnused {
+ void usedInSubclass() {}
+}
+
+class ClassA extends UsedAsBaseClass
+ implements UsedAsInterface, InstantiatedButMethodsUnused {
+ void usedInSubclass() {}
+}
+
+class ClassB extends UsedAsBaseClass
+ implements UsedAsInterface, InstantiatedButMethodsUnused {
+ void usedInSubclass() {}
+ void calledFromSubclass() {}
+}
+
+void baseClassCall(UsedAsBaseClass object) {}
+void interfaceCall(UsedAsInterface object) {}
+void exactCallA(ClassA object) {}
+void exactCallB(ClassB object) {}
+unusedTopLevel() {}
+usedTopLevel() {}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/unused_methods.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/unused_methods.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9d94c52
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/unused_methods.dart.textual_outline_modelled.expect
@@ -0,0 +1,37 @@
+// @dart = 2.6
+abstract class UsedAsBaseClass {
+ void calledFromB() {}
+ void calledFromSubclass() {}
+ void usedInSubclass() {}
+}
+
+class ClassA extends UsedAsBaseClass
+ implements UsedAsInterface, InstantiatedButMethodsUnused {
+ void usedInSubclass() {}
+}
+
+class ClassB extends UsedAsBaseClass
+ implements UsedAsInterface, InstantiatedButMethodsUnused {
+ void calledFromSubclass() {}
+ void usedInSubclass() {}
+}
+
+class InstantiatedButMethodsUnused {
+ void usedInSubclass() {}
+}
+
+class UnusedClass {
+ UnusedClass() {}
+}
+
+class UsedAsInterface {
+ void usedInSubclass() {}
+}
+
+main() {}
+unusedTopLevel() {}
+usedTopLevel() {}
+void baseClassCall(UsedAsBaseClass object) {}
+void exactCallA(ClassA object) {}
+void exactCallB(ClassB object) {}
+void interfaceCall(UsedAsInterface object) {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/var_as_type_name.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/var_as_type_name.dart.textual_outline.expect
new file mode 100644
index 0000000..75b4c1c
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/var_as_type_name.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+class A {
+ Map<String, var> m;
+}
+main() { }
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/void_methods.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/void_methods.dart.textual_outline.expect
new file mode 100644
index 0000000..2121500
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/void_methods.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+class Foo {
+ List list = [1, 2, 3];
+ set first(x) => list[0] = x;
+ operator []=(x, y) => list[x] = y;
+ void clear() => list.clear();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/void_methods.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/void_methods.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e233a9b
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/void_methods.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+class Foo {
+ List list = [1, 2, 3];
+ operator []=(x, y) => list[x] = y;
+ set first(x) => list[0] = x;
+ void clear() => list.clear();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/warn_unresolved_sends.dart.textual_outline.expect b/pkg/front_end/testcases/general_nnbd_opt_out/warn_unresolved_sends.dart.textual_outline.expect
new file mode 100644
index 0000000..a0231de
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/warn_unresolved_sends.dart.textual_outline.expect
@@ -0,0 +1,24 @@
+// @dart = 2.6
+class C {
+ var superField;
+ superMethod() {}
+ get setterOnly => null;
+ void set setterOnly(_) {}
+ get getterOnly => null;
+ void set getterOnly(_) {}
+}
+
+class D extends C {
+ var field;
+ void set setterOnly(_) {}
+ get getterOnly => null;
+ method() {}
+ void test() {}
+}
+
+class E extends D {
+ var missingField;
+ void missingMethod() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/warn_unresolved_sends.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general_nnbd_opt_out/warn_unresolved_sends.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cce7cbc
--- /dev/null
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/warn_unresolved_sends.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+// @dart = 2.6
+class C {
+ get getterOnly => null;
+ get setterOnly => null;
+ superMethod() {}
+ var superField;
+ void set getterOnly(_) {}
+ void set setterOnly(_) {}
+}
+
+class D extends C {
+ get getterOnly => null;
+ method() {}
+ var field;
+ void set setterOnly(_) {}
+ void test() {}
+}
+
+class E extends D {
+ var missingField;
+ void missingMethod() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/implicit_getter_calls/getter_call.dart.textual_outline.expect b/pkg/front_end/testcases/implicit_getter_calls/getter_call.dart.textual_outline.expect
new file mode 100644
index 0000000..d9d43c9
--- /dev/null
+++ b/pkg/front_end/testcases/implicit_getter_calls/getter_call.dart.textual_outline.expect
@@ -0,0 +1,52 @@
+bool enableRead = true;
+int read(int value) => enableRead ? value : -1;
+int method1() => 0;
+int method2(int a) => -a;
+int method3(int a, int b) => a - b;
+int method4(int a, [int b = 0]) => a - b;
+int method5([int a = 0, int b = 0]) => a - b;
+int method6(int a, {int b = 0}) => a - b;
+int method7({int a = 0, int b = 0}) => a - b;
+
+class Class {
+ Function field1a = method1;
+ int Function() field1b = method1;
+ int Function(int a) field2 = method2;
+ int Function(int a, int b) field3 = method3;
+ int Function(int a, [int b]) field4 = method4;
+ int Function([int a, int b]) field5 = method5;
+ int Function(int a, {int b}) field6 = method6;
+ int Function({int a, int b}) field7 = method7;
+ Function get getter1a => method1;
+ int Function() get getter1b => method1;
+ int Function(int a) get getter2 => method2;
+ int Function(int a, int b) get getter3 => method3;
+ int Function(int a, [int b]) get getter4 => method4;
+ int Function([int a, int b]) get getter5 => method5;
+ int Function(int a, {int b}) get getter6 => method6;
+ int Function({int a, int b}) get getter7 => method7;
+}
+
+class Subclass extends Class {
+ Function get field1a {}
+ int Function() get field1b {}
+ int Function(int a) get field2 {}
+ int Function(int a, int b) get field3 {}
+ int Function(int a, [int b]) get field4 {}
+ int Function([int a, int b]) get field5 {}
+ int Function(int a, {int b}) get field6 {}
+ int Function({int a, int b}) get field7 {}
+ Function get getter1a {}
+ int Function() get getter1b {}
+ int Function(int a) get getter2 {}
+ int Function(int a, int b) get getter3 {}
+ int Function(int a, [int b]) get getter4 {}
+ int Function([int a, int b]) get getter5 {}
+ int Function(int a, {int b}) get getter6 {}
+ int Function({int a, int b}) get getter7 {}
+}
+
+main() {}
+callField(Class c) {}
+callGetter(Class c) {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/implicit_getter_calls/getter_call.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/implicit_getter_calls/getter_call.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fafec6e
--- /dev/null
+++ b/pkg/front_end/testcases/implicit_getter_calls/getter_call.dart.textual_outline_modelled.expect
@@ -0,0 +1,52 @@
+bool enableRead = true;
+callField(Class c) {}
+callGetter(Class c) {}
+
+class Class {
+ Function field1a = method1;
+ Function get getter1a => method1;
+ int Function() field1b = method1;
+ int Function() get getter1b => method1;
+ int Function([int a, int b]) field5 = method5;
+ int Function([int a, int b]) get getter5 => method5;
+ int Function(int a) field2 = method2;
+ int Function(int a) get getter2 => method2;
+ int Function(int a, [int b]) field4 = method4;
+ int Function(int a, [int b]) get getter4 => method4;
+ int Function(int a, int b) field3 = method3;
+ int Function(int a, int b) get getter3 => method3;
+ int Function(int a, {int b}) field6 = method6;
+ int Function(int a, {int b}) get getter6 => method6;
+ int Function({int a, int b}) field7 = method7;
+ int Function({int a, int b}) get getter7 => method7;
+}
+
+class Subclass extends Class {
+ Function get field1a {}
+ Function get getter1a {}
+ int Function() get field1b {}
+ int Function() get getter1b {}
+ int Function([int a, int b]) get field5 {}
+ int Function([int a, int b]) get getter5 {}
+ int Function(int a) get field2 {}
+ int Function(int a) get getter2 {}
+ int Function(int a, [int b]) get field4 {}
+ int Function(int a, [int b]) get getter4 {}
+ int Function(int a, int b) get field3 {}
+ int Function(int a, int b) get getter3 {}
+ int Function(int a, {int b}) get field6 {}
+ int Function(int a, {int b}) get getter6 {}
+ int Function({int a, int b}) get field7 {}
+ int Function({int a, int b}) get getter7 {}
+}
+
+expect(expected, actual) {}
+int method1() => 0;
+int method2(int a) => -a;
+int method3(int a, int b) => a - b;
+int method4(int a, [int b = 0]) => a - b;
+int method5([int a = 0, int b = 0]) => a - b;
+int method6(int a, {int b = 0}) => a - b;
+int method7({int a = 0, int b = 0}) => a - b;
+int read(int value) => enableRead ? value : -1;
+main() {}
diff --git a/pkg/front_end/testcases/implicit_getter_calls/this_field_call.dart.textual_outline.expect b/pkg/front_end/testcases/implicit_getter_calls/this_field_call.dart.textual_outline.expect
new file mode 100644
index 0000000..eb3e361
--- /dev/null
+++ b/pkg/front_end/testcases/implicit_getter_calls/this_field_call.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class A<T> {
+ void Function(T) f;
+ A(this.f);
+ foo(T x) => this.f(x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/implicit_getter_calls/this_field_call.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/implicit_getter_calls/this_field_call.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b5116cc
--- /dev/null
+++ b/pkg/front_end/testcases/implicit_getter_calls/this_field_call.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class A<T> {
+ A(this.f);
+ foo(T x) => this.f(x);
+ void Function(T) f;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/abstract_class_instantiation.dart.textual_outline.expect b/pkg/front_end/testcases/inference/abstract_class_instantiation.dart.textual_outline.expect
new file mode 100644
index 0000000..18f0b60
--- /dev/null
+++ b/pkg/front_end/testcases/inference/abstract_class_instantiation.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+abstract class C {}
+
+abstract class D<T> {
+ D(T t);
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/abstract_class_instantiation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/abstract_class_instantiation.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1aba12d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/abstract_class_instantiation.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+abstract class C {}
+
+abstract class D<T> {
+ D(T t);
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/assert.dart.textual_outline.expect b/pkg/front_end/testcases/inference/assert.dart.textual_outline.expect
new file mode 100644
index 0000000..cdb201d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/assert.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+T f<T>() => null;
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/assert.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/assert.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b66d908
--- /dev/null
+++ b/pkg/front_end/testcases/inference/assert.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+T f<T>() => null;
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/assert_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/inference/assert_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..bfa7fcc
--- /dev/null
+++ b/pkg/front_end/testcases/inference/assert_initializer.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+T f<T>() => null;
+
+class C {
+ C.expressionOnly() : assert(f());
+ C.expressionAndMessage() : assert(f(), f());
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/assert_initializer.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/assert_initializer.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9871f1a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/assert_initializer.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+T f<T>() => null;
+
+class C {
+ C.expressionAndMessage() : assert(f(), f());
+ C.expressionOnly() : assert(f());
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/assign_local.dart.textual_outline.expect b/pkg/front_end/testcases/inference/assign_local.dart.textual_outline.expect
new file mode 100644
index 0000000..dab01df
--- /dev/null
+++ b/pkg/front_end/testcases/inference/assign_local.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class A<T> {}
+
+class B<T> extends A<T> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/assign_local.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/assign_local.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..dab01df
--- /dev/null
+++ b/pkg/front_end/testcases/inference/assign_local.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class A<T> {}
+
+class B<T> extends A<T> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/async_await.dart.textual_outline.expect b/pkg/front_end/testcases/inference/async_await.dart.textual_outline.expect
new file mode 100644
index 0000000..0ff2309
--- /dev/null
+++ b/pkg/front_end/testcases/inference/async_await.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+import 'dart:async';
+
+abstract class MyFuture implements Future<int> {}
+
+void test() async {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/async_await.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/async_await.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..28c7ff1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/async_await.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+import 'dart:async';
+
+abstract class MyFuture implements Future<int> {}
+
+main() {}
+void test() async {}
diff --git a/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.textual_outline.expect b/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.textual_outline.expect
new file mode 100644
index 0000000..2394f32
--- /dev/null
+++ b/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+import 'dart:async';
+
+Future<int> futureInt = null;
+var f = () => futureInt;
+var g = () async => futureInt;
+main() {}
diff --git a/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..92b84b4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+import 'dart:async';
+
+Future<int> futureInt = null;
+main() {}
+var f = () => futureInt;
+var g = () async => futureInt;
diff --git a/pkg/front_end/testcases/inference/async_closure_return_type_future.dart.textual_outline.expect b/pkg/front_end/testcases/inference/async_closure_return_type_future.dart.textual_outline.expect
new file mode 100644
index 0000000..d5d8f30
--- /dev/null
+++ b/pkg/front_end/testcases/inference/async_closure_return_type_future.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+var f = () async => 0;
+main() {}
diff --git a/pkg/front_end/testcases/inference/async_closure_return_type_future.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/async_closure_return_type_future.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..95b148d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/async_closure_return_type_future.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+var f = () async => 0;
diff --git a/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.textual_outline.expect b/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.textual_outline.expect
new file mode 100644
index 0000000..acecf1d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+import 'dart:async';
+
+FutureOr<int> futureOrInt = null;
+var f = () => futureOrInt;
+var g = () async => futureOrInt;
+main() {}
diff --git a/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c8ad68a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+import 'dart:async';
+
+FutureOr<int> futureOrInt = null;
+main() {}
+var f = () => futureOrInt;
+var g = () async => futureOrInt;
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.textual_outline.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.textual_outline.expect
new file mode 100644
index 0000000..2d20965
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+import 'dart:async';
+import 'dart:math' show Random;
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0962407
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+import 'dart:async';
+import 'dart:math' show Random;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.textual_outline.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.textual_outline.expect
new file mode 100644
index 0000000..2d20965
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+import 'dart:async';
+import 'dart:math' show Random;
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0962407
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+import 'dart:async';
+import 'dart:math' show Random;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.textual_outline.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.textual_outline.expect
new file mode 100644
index 0000000..2d20965
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+import 'dart:async';
+import 'dart:math' show Random;
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0962407
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+import 'dart:async';
+import 'dart:math' show Random;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_star.dart.textual_outline.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_star.dart.textual_outline.expect
new file mode 100644
index 0000000..242deb6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_star.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+import 'dart:async';
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_star.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_star.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8318b63
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_star.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+import 'dart:async';
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_basic.dart.textual_outline.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_basic.dart.textual_outline.expect
new file mode 100644
index 0000000..a73b3f8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_basic.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+test1() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_basic.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_basic.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..128ffb9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_basic.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+test1() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_basic_void.dart.textual_outline.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_basic_void.dart.textual_outline.expect
new file mode 100644
index 0000000..f59c3c4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_basic_void.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+f() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_basic_void.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_basic_void.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f59c3c4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_basic_void.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+f() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference.dart.textual_outline.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference_top_level.dart.textual_outline.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference_top_level.dart.textual_outline.expect
new file mode 100644
index 0000000..0a7258b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference_top_level.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+String f() => null;
+var g = f;
+main() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference_top_level.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference_top_level.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0b7a3a9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference_top_level.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+String f() => null;
+main() {}
+var g = f;
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.textual_outline.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.textual_outline.expect
new file mode 100644
index 0000000..8519dee
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+import 'dart:async';
+
+main() async {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8519dee
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+import 'dart:async';
+
+main() async {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.textual_outline.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.textual_outline.expect
new file mode 100644
index 0000000..8519dee
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+import 'dart:async';
+
+main() async {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8519dee
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+import 'dart:async';
+
+main() async {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync.dart.textual_outline.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync.dart.textual_outline.expect
new file mode 100644
index 0000000..4a1f36a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+var h = null;
+void foo(int f(Object _)) {}
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1183aa1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+main() {}
+test() {}
+var h = null;
+void foo(int f(Object _)) {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync_star.dart.textual_outline.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync_star.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync_star.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync_star.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync_star.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync_star.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_lub.dart.textual_outline.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_lub.dart.textual_outline.expect
new file mode 100644
index 0000000..2d51ce5
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_lub.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+import 'dart:math' show Random;
+
+test2() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_lub.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_lub.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..02a9440
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_lub.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+import 'dart:math' show Random;
+
+main() {}
+test2() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_nested_lambdas.dart.textual_outline.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_nested_lambdas.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_nested_lambdas.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_nested_lambdas.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_nested_lambdas.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_nested_lambdas.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_no_return.dart.textual_outline.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_no_return.dart.textual_outline.expect
new file mode 100644
index 0000000..a73b3f8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_no_return.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+test1() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_no_return.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_no_return.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..128ffb9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_no_return.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+test1() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_returns.dart.textual_outline.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_returns.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_returns.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_returns.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_returns.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_returns.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_sync_star.dart.textual_outline.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_sync_star.dart.textual_outline.expect
new file mode 100644
index 0000000..c70c84a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_sync_star.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_sync_star.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_sync_star.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..10819ea
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_sync_star.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_void_context.dart.textual_outline.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_void_context.dart.textual_outline.expect
new file mode 100644
index 0000000..f59c3c4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_void_context.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+f() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_void_context.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_void_context.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f59c3c4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_void_context.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+f() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/bottom.dart.textual_outline.expect b/pkg/front_end/testcases/inference/bottom.dart.textual_outline.expect
new file mode 100644
index 0000000..3a3a838
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bottom.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+var v = null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/bottom.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/bottom.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..513df85
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bottom.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+var v = null;
diff --git a/pkg/front_end/testcases/inference/bottom_in_closure.dart.textual_outline.expect b/pkg/front_end/testcases/inference/bottom_in_closure.dart.textual_outline.expect
new file mode 100644
index 0000000..5c8173a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bottom_in_closure.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+var v = () => null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/bottom_in_closure.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/bottom_in_closure.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..09b085b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bottom_in_closure.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+var v = () => null;
diff --git a/pkg/front_end/testcases/inference/bug30251.dart.textual_outline.expect b/pkg/front_end/testcases/inference/bug30251.dart.textual_outline.expect
new file mode 100644
index 0000000..8c82e9b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug30251.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+T f<T>(T t) => t;
+
+class C {
+ final x;
+ C(int p) : x = f(1 + p);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/bug30251.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/bug30251.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a9f43dc
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug30251.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+T f<T>(T t) => t;
+
+class C {
+ C(int p) : x = f(1 + p);
+ final x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/bug30620.dart.textual_outline.expect b/pkg/front_end/testcases/inference/bug30620.dart.textual_outline.expect
new file mode 100644
index 0000000..fec1eb3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug30620.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+class A {
+ final String foo;
+ A(this.foo);
+ bool operator ==(Object other) => other is A && other.foo == this.foo;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/bug30620.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/bug30620.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0fcdf5f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug30620.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+class A {
+ A(this.foo);
+ bool operator ==(Object other) => other is A && other.foo == this.foo;
+ final String foo;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/bug30620_b.dart.textual_outline.expect b/pkg/front_end/testcases/inference/bug30620_b.dart.textual_outline.expect
new file mode 100644
index 0000000..503a2af
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug30620_b.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class A {
+ final String foo;
+ A(this.foo);
+ bool operator ==(Object other) =>
+ other is A && other.foo == this.foo && other.foo == this.foo;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/bug30620_b.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/bug30620_b.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..329f32b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug30620_b.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class A {
+ A(this.foo);
+ bool operator ==(Object other) =>
+ other is A && other.foo == this.foo && other.foo == this.foo;
+ final String foo;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/bug30620_c.dart.textual_outline.expect b/pkg/front_end/testcases/inference/bug30620_c.dart.textual_outline.expect
new file mode 100644
index 0000000..42c642b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug30620_c.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+class A {
+ final String foo;
+ A(this.foo);
+ bool operator ==(Object other) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/bug30620_c.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/bug30620_c.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6ecf601
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug30620_c.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+class A {
+ A(this.foo);
+ bool operator ==(Object other) {}
+ final String foo;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/bug30620_d.dart.textual_outline.expect b/pkg/front_end/testcases/inference/bug30620_d.dart.textual_outline.expect
new file mode 100644
index 0000000..ce7f4b7
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug30620_d.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+String foo(obj) => obj is String ? obj.toUpperCase() : null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/bug30620_d.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/bug30620_d.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ce7f4b7
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug30620_d.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+String foo(obj) => obj is String ? obj.toUpperCase() : null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/bug30624.dart.textual_outline.expect b/pkg/front_end/testcases/inference/bug30624.dart.textual_outline.expect
new file mode 100644
index 0000000..2224470
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug30624.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+void foo<E>(C<E> c, int cmp(E a, E b)) {}
+
+class C<E> {
+ void barA([int cmp(E a, E b)]) {}
+ void barB([int cmp(E a, E b)]) {}
+ void barC([int cmp(E a, E b)]) {}
+ void barD([int cmp(E a, E b)]) {}
+ void barE([int cmp(E a, E b)]) {}
+ void barF([int cmp(E a, E b)]) {}
+ static int _default(a, b) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/bug30624.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/bug30624.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bb56b97
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug30624.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+library test;
+
+class C<E> {
+ static int _default(a, b) {}
+ void barA([int cmp(E a, E b)]) {}
+ void barB([int cmp(E a, E b)]) {}
+ void barC([int cmp(E a, E b)]) {}
+ void barD([int cmp(E a, E b)]) {}
+ void barE([int cmp(E a, E b)]) {}
+ void barF([int cmp(E a, E b)]) {}
+}
+
+main() {}
+void foo<E>(C<E> c, int cmp(E a, E b)) {}
diff --git a/pkg/front_end/testcases/inference/bug31132.dart.textual_outline.expect b/pkg/front_end/testcases/inference/bug31132.dart.textual_outline.expect
new file mode 100644
index 0000000..977a33d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug31132.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class B {}
+
+class C extends B {
+ var z;
+}
+
+void test(B x) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/bug31132.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/bug31132.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b742b0c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug31132.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class B {}
+
+class C extends B {
+ var z;
+}
+
+main() {}
+void test(B x) {}
diff --git a/pkg/front_end/testcases/inference/bug31133.dart.textual_outline.expect b/pkg/front_end/testcases/inference/bug31133.dart.textual_outline.expect
new file mode 100644
index 0000000..a6bcf94
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug31133.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/bug31133.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/bug31133.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..72a3ba0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug31133.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/bug31436.dart.textual_outline.expect b/pkg/front_end/testcases/inference/bug31436.dart.textual_outline.expect
new file mode 100644
index 0000000..eaa5347
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug31436.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+void block_test() {}
+void arrow_test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/bug31436.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/bug31436.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2b6b538
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug31436.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+main() {}
+void arrow_test() {}
+void block_test() {}
diff --git a/pkg/front_end/testcases/inference/bug32291.dart.textual_outline.expect b/pkg/front_end/testcases/inference/bug32291.dart.textual_outline.expect
new file mode 100644
index 0000000..c07c403
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug32291.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+void main() {}
diff --git a/pkg/front_end/testcases/inference/bug32291.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/bug32291.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c07c403
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug32291.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+void main() {}
diff --git a/pkg/front_end/testcases/inference/bug33324.dart.textual_outline.expect b/pkg/front_end/testcases/inference/bug33324.dart.textual_outline.expect
new file mode 100644
index 0000000..b085311
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug33324.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+int foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/bug33324.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/bug33324.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b085311
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug33324.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+int foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/call_corner_cases.dart.textual_outline.expect b/pkg/front_end/testcases/inference/call_corner_cases.dart.textual_outline.expect
new file mode 100644
index 0000000..48e6f56
--- /dev/null
+++ b/pkg/front_end/testcases/inference/call_corner_cases.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+library test;
+
+class A {
+ int call() => 0;
+}
+
+class B {
+ A get call => new A();
+}
+
+class D {
+ A fieldA = new A();
+ A get getA => new A();
+ B fieldB = new B();
+ B get getB => new B();
+}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/call_corner_cases.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/call_corner_cases.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..73709ae
--- /dev/null
+++ b/pkg/front_end/testcases/inference/call_corner_cases.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+library test;
+
+class A {
+ int call() => 0;
+}
+
+class B {
+ A get call => new A();
+}
+
+class D {
+ A fieldA = new A();
+ A get getA => new A();
+ B fieldB = new B();
+ B get getB => new B();
+}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/callable_generic_class.dart.textual_outline.expect b/pkg/front_end/testcases/inference/callable_generic_class.dart.textual_outline.expect
new file mode 100644
index 0000000..0114b01
--- /dev/null
+++ b/pkg/front_end/testcases/inference/callable_generic_class.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+class ActionDispatcher<P> {
+ void call([P value]) {}
+}
+
+class Bar {}
+
+class FooActions {
+ ActionDispatcher<Bar> get foo => new ActionDispatcher<Bar>();
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/inference/callable_generic_class.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/callable_generic_class.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0114b01
--- /dev/null
+++ b/pkg/front_end/testcases/inference/callable_generic_class.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+class ActionDispatcher<P> {
+ void call([P value]) {}
+}
+
+class Bar {}
+
+class FooActions {
+ ActionDispatcher<Bar> get foo => new ActionDispatcher<Bar>();
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/inference/circular_method_inference.dart.textual_outline.expect b/pkg/front_end/testcases/inference/circular_method_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..10f2489
--- /dev/null
+++ b/pkg/front_end/testcases/inference/circular_method_inference.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+abstract class A extends B {
+ f(x);
+}
+
+abstract class B extends A {
+ f(x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/circular_method_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/circular_method_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..10f2489
--- /dev/null
+++ b/pkg/front_end/testcases/inference/circular_method_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+abstract class A extends B {
+ f(x);
+}
+
+abstract class B extends A {
+ f(x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/circular_reference_via_closures.dart.textual_outline.expect b/pkg/front_end/testcases/inference/circular_reference_via_closures.dart.textual_outline.expect
new file mode 100644
index 0000000..34a8c28
--- /dev/null
+++ b/pkg/front_end/testcases/inference/circular_reference_via_closures.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+var x = () => y;
+var y = () => x;
+main() {}
diff --git a/pkg/front_end/testcases/inference/circular_reference_via_closures.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/circular_reference_via_closures.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1be8547
--- /dev/null
+++ b/pkg/front_end/testcases/inference/circular_reference_via_closures.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+main() {}
+var x = () => y;
+var y = () => x;
diff --git a/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart.textual_outline.expect b/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart.textual_outline.expect
new file mode 100644
index 0000000..34a8c28
--- /dev/null
+++ b/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+var x = () => y;
+var y = () => x;
+main() {}
diff --git a/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1be8547
--- /dev/null
+++ b/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+main() {}
+var x = () => y;
+var y = () => x;
diff --git a/pkg/front_end/testcases/inference/closure_param_null_to_object.dart.textual_outline.expect b/pkg/front_end/testcases/inference/closure_param_null_to_object.dart.textual_outline.expect
new file mode 100644
index 0000000..a6bcf94
--- /dev/null
+++ b/pkg/front_end/testcases/inference/closure_param_null_to_object.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/closure_param_null_to_object.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/closure_param_null_to_object.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..72a3ba0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/closure_param_null_to_object.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/coerce_bottom_and_null_types.dart.textual_outline.expect b/pkg/front_end/testcases/inference/coerce_bottom_and_null_types.dart.textual_outline.expect
new file mode 100644
index 0000000..f59c3c4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/coerce_bottom_and_null_types.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+f() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/coerce_bottom_and_null_types.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/coerce_bottom_and_null_types.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f59c3c4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/coerce_bottom_and_null_types.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+f() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/complex_predecrement.dart.textual_outline.expect b/pkg/front_end/testcases/inference/complex_predecrement.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/complex_predecrement.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/complex_predecrement.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/complex_predecrement.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/complex_predecrement.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/conditional_lub.dart.textual_outline.expect b/pkg/front_end/testcases/inference/conditional_lub.dart.textual_outline.expect
new file mode 100644
index 0000000..8dcdc49
--- /dev/null
+++ b/pkg/front_end/testcases/inference/conditional_lub.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+bool b = true;
+int x = 0;
+double y = 0.0;
+var z = b ? x : y;
+main() {}
diff --git a/pkg/front_end/testcases/inference/conditional_lub.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/conditional_lub.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2c98a8f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/conditional_lub.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+bool b = true;
+double y = 0.0;
+int x = 0;
+main() {}
+var z = b ? x : y;
diff --git a/pkg/front_end/testcases/inference/conditional_upwards_inference.dart.textual_outline.expect b/pkg/front_end/testcases/inference/conditional_upwards_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..65185f2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/conditional_upwards_inference.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C<T> {
+ C(List<T> x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/conditional_upwards_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/conditional_upwards_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..65185f2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/conditional_upwards_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C<T> {
+ C(List<T> x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/conflicting_fields.dart.textual_outline.expect b/pkg/front_end/testcases/inference/conflicting_fields.dart.textual_outline.expect
new file mode 100644
index 0000000..411a1c3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/conflicting_fields.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+class A {
+ dynamic field1;
+ int field2;
+}
+
+class I {
+ int field1;
+ dynamic field2;
+}
+
+class B extends A implements I {
+ get field1 => null;
+ get field2 => null;
+ set field1(value) {}
+ set field2(value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/conflicting_fields.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/conflicting_fields.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..145da2c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/conflicting_fields.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+class A {
+ dynamic field1;
+ int field2;
+}
+
+class B extends A implements I {
+ get field1 => null;
+ get field2 => null;
+ set field1(value) {}
+ set field2(value) {}
+}
+
+class I {
+ dynamic field2;
+ int field1;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/conflicts_can_happen.dart.textual_outline.expect b/pkg/front_end/testcases/inference/conflicts_can_happen.dart.textual_outline.expect
new file mode 100644
index 0000000..0cae63c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/conflicts_can_happen.dart.textual_outline.expect
@@ -0,0 +1,27 @@
+library test;
+
+class I1 {
+ int x;
+}
+
+class I2 extends I1 {
+ int y;
+}
+
+class A {
+ final I1 a = null;
+}
+
+class B {
+ final I2 a = null;
+}
+
+class C1 implements A, B {
+ get a => null;
+}
+
+class C2 implements B, A {
+ get a => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/conflicts_can_happen.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/conflicts_can_happen.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fbcfeb5
--- /dev/null
+++ b/pkg/front_end/testcases/inference/conflicts_can_happen.dart.textual_outline_modelled.expect
@@ -0,0 +1,27 @@
+library test;
+
+class A {
+ final I1 a = null;
+}
+
+class B {
+ final I2 a = null;
+}
+
+class C1 implements A, B {
+ get a => null;
+}
+
+class C2 implements B, A {
+ get a => null;
+}
+
+class I1 {
+ int x;
+}
+
+class I2 extends I1 {
+ int y;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.textual_outline.expect
new file mode 100644
index 0000000..99ab361
--- /dev/null
+++ b/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.textual_outline.expect
@@ -0,0 +1,32 @@
+library test;
+
+class I1 {
+ int x;
+}
+
+class I2 {
+ int y;
+}
+
+class I3 implements I1, I2 {
+ int x;
+ int y;
+}
+
+class A {
+ final I1 a = null;
+}
+
+class B {
+ final I2 a = null;
+}
+
+class C1 implements A, B {
+ I3 get a => null;
+}
+
+class C2 implements A, B {
+ get a => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ae75406
--- /dev/null
+++ b/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.textual_outline_modelled.expect
@@ -0,0 +1,32 @@
+library test;
+
+class A {
+ final I1 a = null;
+}
+
+class B {
+ final I2 a = null;
+}
+
+class C1 implements A, B {
+ I3 get a => null;
+}
+
+class C2 implements A, B {
+ get a => null;
+}
+
+class I1 {
+ int x;
+}
+
+class I2 {
+ int y;
+}
+
+class I3 implements I1, I2 {
+ int x;
+ int y;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_downwards_with_constraint.dart.textual_outline.expect b/pkg/front_end/testcases/inference/constructors_downwards_with_constraint.dart.textual_outline.expect
new file mode 100644
index 0000000..3317fee
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_downwards_with_constraint.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+class A {}
+
+class B extends A {}
+
+class Foo<T extends A> {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_downwards_with_constraint.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/constructors_downwards_with_constraint.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3317fee
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_downwards_with_constraint.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+class A {}
+
+class B extends A {}
+
+class Foo<T extends A> {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.textual_outline.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.textual_outline.expect
new file mode 100644
index 0000000..e5bb6f3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+class C<T> {
+ T t;
+ C(this.t);
+}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..413457c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+class C<T> {
+ C(this.t);
+ T t;
+}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart.textual_outline.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart.textual_outline.expect
new file mode 100644
index 0000000..5cd2e23
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+library test;
+
+class A {}
+
+typedef T F<T>();
+
+class C<T extends A> {
+ C(F<T> f);
+}
+
+class NotA {}
+
+NotA myF() => null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b220a27
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+library test;
+
+NotA myF() => null;
+
+class A {}
+
+class C<T extends A> {
+ C(F<T> f);
+}
+
+class NotA {}
+
+main() {}
+typedef T F<T>();
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_const.dart.textual_outline.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_const.dart.textual_outline.expect
new file mode 100644
index 0000000..a3c6d99
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_const.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C<T> {
+ final T t;
+ const C(this.t);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_const.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_const.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5d6c509
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_const.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C<T> {
+ const C(this.t);
+ final T t;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_const_with_upper_bound.dart.textual_outline.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_const_with_upper_bound.dart.textual_outline.expect
new file mode 100644
index 0000000..228e705
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_const_with_upper_bound.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+class C<T extends num> {
+ final T x;
+ const C(this.x);
+}
+
+class D<T extends num> {
+ const D();
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_const_with_upper_bound.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_const_with_upper_bound.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..df658a6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_const_with_upper_bound.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+class C<T extends num> {
+ const C(this.x);
+ final T x;
+}
+
+class D<T extends num> {
+ const D();
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_downwards_from_constructor.dart.textual_outline.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_downwards_from_constructor.dart.textual_outline.expect
new file mode 100644
index 0000000..af80416
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_downwards_from_constructor.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C<T> {
+ C(List<T> list);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_downwards_from_constructor.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_downwards_from_constructor.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..af80416
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_downwards_from_constructor.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C<T> {
+ C(List<T> list);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.textual_outline.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.textual_outline.expect
new file mode 100644
index 0000000..6328816
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C<T> {
+ T t;
+ C._();
+ factory C(T t) {}
+}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..33f4f60
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C<T> {
+ C._();
+ T t;
+ factory C(T t) {}
+}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory_calls_constructor.dart.textual_outline.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory_calls_constructor.dart.textual_outline.expect
new file mode 100644
index 0000000..e3c1708
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory_calls_constructor.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class A<T> {
+ A<T> f = new A();
+ A();
+ factory A.factory() => new A();
+ A<T> m() => new A();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory_calls_constructor.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory_calls_constructor.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2f3f4f5
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory_calls_constructor.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class A<T> {
+ A();
+ A<T> f = new A();
+ A<T> m() => new A();
+ factory A.factory() => new A();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named.dart.textual_outline.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named.dart.textual_outline.expect
new file mode 100644
index 0000000..7dd7722
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C<T> {
+ T t;
+ C.named(List<T> t);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..93750d1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C<T> {
+ C.named(List<T> t);
+ T t;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named_factory.dart.textual_outline.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named_factory.dart.textual_outline.expect
new file mode 100644
index 0000000..6019b7f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named_factory.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+class C<T> {
+ T t;
+ C();
+ factory C.named(T t) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named_factory.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named_factory.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5970e4f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named_factory.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+class C<T> {
+ C();
+ T t;
+ factory C.named(T t) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting.dart.textual_outline.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting.dart.textual_outline.expect
new file mode 100644
index 0000000..ca7d831
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+class C<T> {
+ T t;
+ C(this.t);
+ C.named(List<T> t) : this(t[0]);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..010a7db
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+class C<T> {
+ C(this.t);
+ C.named(List<T> t) : this(t[0]);
+ T t;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory.dart.textual_outline.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory.dart.textual_outline.expect
new file mode 100644
index 0000000..86de0c0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+library test;
+
+abstract class C<T> {
+ T get t;
+ void set t(T x);
+ factory C(T t) = CImpl<T>;
+}
+
+class CImpl<T> implements C<T> {
+ T t;
+ CImpl(this.t);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8bc935e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+library test;
+
+abstract class C<T> {
+ T get t;
+ factory C(T t) = CImpl<T>;
+ void set t(T x);
+}
+
+class CImpl<T> implements C<T> {
+ CImpl(this.t);
+ T t;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory_to_factory.dart.textual_outline.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory_to_factory.dart.textual_outline.expect
new file mode 100644
index 0000000..f75f8c2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory_to_factory.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+abstract class C<T> {
+ T get t;
+ void set t(T x);
+ factory C(T t) = CImpl<T>;
+}
+
+class CImpl<T> implements C<T> {
+ T t;
+ CImpl._(this.t);
+ factory CImpl(T t) => new CImpl._(t);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory_to_factory.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory_to_factory.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2ee205e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory_to_factory.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+abstract class C<T> {
+ T get t;
+ factory C(T t) = CImpl<T>;
+ void set t(T x);
+}
+
+class CImpl<T> implements C<T> {
+ CImpl._(this.t);
+ T t;
+ factory CImpl(T t) => new CImpl._(t);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.textual_outline.expect b/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.textual_outline.expect
new file mode 100644
index 0000000..9663430
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+class Cloneable<T> {}
+
+class Pair<T extends Cloneable<T>, U extends Cloneable<U>> {
+ T t;
+ U u;
+ Pair(this.t, this.u);
+ Pair._();
+ Pair<U, T> get reversed => new Pair(u, t);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..dd68431
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+class Cloneable<T> {}
+
+class Pair<T extends Cloneable<T>, U extends Cloneable<U>> {
+ Pair(this.t, this.u);
+ Pair._();
+ Pair<U, T> get reversed => new Pair(u, t);
+ T t;
+ U u;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_reverse_type_parameters.dart.textual_outline.expect b/pkg/front_end/testcases/inference/constructors_reverse_type_parameters.dart.textual_outline.expect
new file mode 100644
index 0000000..08b5285
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_reverse_type_parameters.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class Pair<T, U> {
+ T t;
+ U u;
+ Pair(this.t, this.u);
+ Pair<U, T> get reversed => new Pair(u, t);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_reverse_type_parameters.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/constructors_reverse_type_parameters.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..32b945d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_reverse_type_parameters.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class Pair<T, U> {
+ Pair(this.t, this.u);
+ Pair<U, T> get reversed => new Pair(u, t);
+ T t;
+ U u;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_too_many_positional_arguments.dart.textual_outline.expect b/pkg/front_end/testcases/inference/constructors_too_many_positional_arguments.dart.textual_outline.expect
new file mode 100644
index 0000000..d3ee256
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_too_many_positional_arguments.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+class A<T> {}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/constructors_too_many_positional_arguments.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/constructors_too_many_positional_arguments.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a4a2d50
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_too_many_positional_arguments.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+class A<T> {}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/do_not_infer_overridden_fields_that_explicitly_say_dynamic_infer.dart.textual_outline.expect b/pkg/front_end/testcases/inference/do_not_infer_overridden_fields_that_explicitly_say_dynamic_infer.dart.textual_outline.expect
new file mode 100644
index 0000000..27f0e71
--- /dev/null
+++ b/pkg/front_end/testcases/inference/do_not_infer_overridden_fields_that_explicitly_say_dynamic_infer.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+class A {
+ final int x = 2;
+}
+
+class B implements A {
+ dynamic get x => 3;
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/do_not_infer_overridden_fields_that_explicitly_say_dynamic_infer.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/do_not_infer_overridden_fields_that_explicitly_say_dynamic_infer.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..27f0e71
--- /dev/null
+++ b/pkg/front_end/testcases/inference/do_not_infer_overridden_fields_that_explicitly_say_dynamic_infer.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+class A {
+ final int x = 2;
+}
+
+class B implements A {
+ dynamic get x => 3;
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/dont_infer_field_type_when_initializer_is_null.dart.textual_outline.expect b/pkg/front_end/testcases/inference/dont_infer_field_type_when_initializer_is_null.dart.textual_outline.expect
new file mode 100644
index 0000000..0114cbd
--- /dev/null
+++ b/pkg/front_end/testcases/inference/dont_infer_field_type_when_initializer_is_null.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+var x = null;
+var y = 3;
+
+class A {
+ static var x = null;
+ static var y = 3;
+ var x2 = null;
+ var y2 = 3;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/dont_infer_field_type_when_initializer_is_null.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/dont_infer_field_type_when_initializer_is_null.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..295e0ea
--- /dev/null
+++ b/pkg/front_end/testcases/inference/dont_infer_field_type_when_initializer_is_null.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+class A {
+ static var x = null;
+ static var y = 3;
+ var x2 = null;
+ var y2 = 3;
+}
+
+main() {}
+var x = null;
+var y = 3;
diff --git a/pkg/front_end/testcases/inference/dont_infer_type_on_dynamic.dart.textual_outline.expect b/pkg/front_end/testcases/inference/dont_infer_type_on_dynamic.dart.textual_outline.expect
new file mode 100644
index 0000000..c70c84a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/dont_infer_type_on_dynamic.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/dont_infer_type_on_dynamic.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/dont_infer_type_on_dynamic.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..10819ea
--- /dev/null
+++ b/pkg/front_end/testcases/inference/dont_infer_type_on_dynamic.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/dont_infer_type_when_initializer_is_null.dart.textual_outline.expect b/pkg/front_end/testcases/inference/dont_infer_type_when_initializer_is_null.dart.textual_outline.expect
new file mode 100644
index 0000000..c70c84a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/dont_infer_type_when_initializer_is_null.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/dont_infer_type_when_initializer_is_null.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/dont_infer_type_when_initializer_is_null.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..10819ea
--- /dev/null
+++ b/pkg/front_end/testcases/inference/dont_infer_type_when_initializer_is_null.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart.textual_outline.expect
new file mode 100644
index 0000000..1e0f033
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+import 'dart:math';
+
+f() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1e0f033
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+import 'dart:math';
+
+f() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/downward_inference_miscellaneous.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downward_inference_miscellaneous.dart.textual_outline.expect
new file mode 100644
index 0000000..f36fe08
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downward_inference_miscellaneous.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+typedef T Function2<S, T>(S x);
+
+class A<T> {
+ Function2<T, T> x;
+ A(this.x);
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/inference/downward_inference_miscellaneous.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downward_inference_miscellaneous.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..697ff80
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downward_inference_miscellaneous.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+class A<T> {
+ A(this.x);
+ Function2<T, T> x;
+}
+
+typedef T Function2<S, T>(S x);
+void main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.textual_outline.expect
new file mode 100644
index 0000000..16ed9ce
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+abstract class A {
+ Iterable<String> get foo;
+}
+
+class B implements A {
+ final foo = const [];
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..16ed9ce
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+abstract class A {
+ Iterable<String> get foo;
+}
+
+class B implements A {
+ final foo = const [];
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations.dart.textual_outline.expect
new file mode 100644
index 0000000..fb5daf2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+library test;
+
+class Foo {
+ const Foo(List<String> l);
+ const Foo.named(List<String> l);
+}
+
+@Foo(const [])
+class Bar {}
+
+@Foo.named(const [])
+class Baz {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..af71307
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+library test;
+
+@Foo(const [])
+class Bar {}
+
+@Foo.named(const [])
+class Baz {}
+
+class Foo {
+ const Foo(List<String> l);
+ const Foo.named(List<String> l);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_class_members.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_class_members.dart.textual_outline.expect
new file mode 100644
index 0000000..3cc94f4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_class_members.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+library test;
+
+class Foo {
+ const Foo(List<String> l);
+}
+
+abstract class Bar {
+ @Foo(const [])
+ Bar();
+ @Foo(const [])
+ var x;
+ @Foo(const [])
+ void f();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_class_members.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_class_members.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..900fab8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_class_members.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+library test;
+
+abstract class Bar {
+ @Foo(const [])
+ Bar();
+ @Foo(const [])
+ var x;
+ @Foo(const [])
+ void f();
+}
+
+class Foo {
+ const Foo(List<String> l);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart.textual_outline.expect
new file mode 100644
index 0000000..d40f333
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class Foo {
+ const Foo(List<String> l);
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0818562
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class Foo {
+ const Foo(List<String> l);
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_locals.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_locals.dart.textual_outline.expect
new file mode 100644
index 0000000..d40f333
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_locals.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class Foo {
+ const Foo(List<String> l);
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_locals.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_locals.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0818562
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_locals.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class Foo {
+ const Foo(List<String> l);
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_locals_referring_to_locals.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_locals_referring_to_locals.dart.textual_outline.expect
new file mode 100644
index 0000000..45f63cd
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_locals_referring_to_locals.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class Foo {
+ const Foo(dynamic l);
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_locals_referring_to_locals.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_locals_referring_to_locals.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..109def4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_locals_referring_to_locals.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class Foo {
+ const Foo(dynamic l);
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter.dart.textual_outline.expect
new file mode 100644
index 0000000..85424cc
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+class Foo {
+ const Foo(List<String> l);
+}
+
+void f(@Foo(const []) x) {}
+
+class C {
+ void m(@Foo(const []) x) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3d34b57
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+class C {
+ void m(@Foo(const []) x) {}
+}
+
+class Foo {
+ const Foo(List<String> l);
+}
+
+main() {}
+void f(@Foo(const []) x) {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart.textual_outline.expect
new file mode 100644
index 0000000..d40f333
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class Foo {
+ const Foo(List<String> l);
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0818562
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class Foo {
+ const Foo(List<String> l);
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable.dart.textual_outline.expect
new file mode 100644
index 0000000..fdc2d82
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+library test;
+
+class Foo {
+ const Foo(List<String> l);
+}
+
+class C<@Foo(const []) T> {}
+
+typedef void F<@Foo(const []) T>();
+void f<@Foo(const []) T>() {}
+
+class D {
+ void m<@Foo(const []) T>() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..26f3f04
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+class C<@Foo(const []) T> {}
+
+class D {
+ void m<@Foo(const []) T>() {}
+}
+
+class Foo {
+ const Foo(List<String> l);
+}
+
+main() {}
+typedef void F<@Foo(const []) T>();
+void f<@Foo(const []) T>() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart.textual_outline.expect
new file mode 100644
index 0000000..d40f333
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class Foo {
+ const Foo(List<String> l);
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0818562
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class Foo {
+ const Foo(List<String> l);
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_typedef.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_typedef.dart.textual_outline.expect
new file mode 100644
index 0000000..e7416ab
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_typedef.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+class Foo {
+ const Foo(List<String> l);
+}
+
+@Foo(const [])
+typedef void F();
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_typedef.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_typedef.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9b53595
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_typedef.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+@Foo(const [])
+typedef void F();
+
+class Foo {
+ const Foo(List<String> l);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_assignment_statements.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_assignment_statements.dart.textual_outline.expect
new file mode 100644
index 0000000..a6bcf94
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_assignment_statements.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_assignment_statements.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_assignment_statements.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..72a3ba0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_assignment_statements.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.textual_outline.expect
new file mode 100644
index 0000000..122c5de
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+import 'dart:async';
+
+Future main() async {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..122c5de
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+import 'dart:async';
+
+Future main() async {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.textual_outline.expect
new file mode 100644
index 0000000..f7b4524
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+import 'dart:async';
+
+abstract class MyStream<T> extends Stream<T> {
+ factory MyStream() => null;
+}
+
+T F<T>() => null;
+Future f() async {}
+Future main() async {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..305c039
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+import 'dart:async';
+
+Future f() async {}
+Future main() async {}
+T F<T>() => null;
+
+abstract class MyStream<T> extends Stream<T> {
+ factory MyStream() => null;
+}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_initializing_formal_default_formal.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_initializing_formal_default_formal.dart.textual_outline.expect
new file mode 100644
index 0000000..af6edf3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_initializing_formal_default_formal.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+typedef T Function2<S, T>([S x]);
+
+class Foo {
+ List<int> x;
+ Foo([this.x = const [1]]);
+ Foo.named([List<int> x = const [1]]);
+}
+
+void f([List<int> l = const [1]]) {}
+Function2<List<int>, String> g = ([llll = const [1]]) => "hello";
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_initializing_formal_default_formal.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_initializing_formal_default_formal.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6ca9e3d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_initializing_formal_default_formal.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+Function2<List<int>, String> g = ([llll = const [1]]) => "hello";
+
+class Foo {
+ Foo([this.x = const [1]]);
+ Foo.named([List<int> x = const [1]]);
+ List<int> x;
+}
+
+main() {}
+typedef T Function2<S, T>([S x]);
+void f([List<int> l = const [1]]) {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_inside_top_level.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_inside_top_level.dart.textual_outline.expect
new file mode 100644
index 0000000..1425d39
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_inside_top_level.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+class A {
+ B<int> b;
+}
+
+class B<T> {
+ B(T x);
+}
+
+var t1 = new A()..b = new B(1);
+var t2 = <B<int>>[new B(2)];
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_inside_top_level.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_inside_top_level.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ac056b3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_inside_top_level.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+class A {
+ B<int> b;
+}
+
+class B<T> {
+ B(T x);
+}
+
+main() {}
+var t1 = new A()..b = new B(1);
+var t2 = <B<int>>[new B(2)];
diff --git a/pkg/front_end/testcases/inference/downwards_inference_inside_top_level_2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_inside_top_level_2.dart.textual_outline.expect
new file mode 100644
index 0000000..0c60385
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_inside_top_level_2.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class A<T> {
+ A(T x);
+}
+
+var t1 = <A<int>>[new A(1)];
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_inside_top_level_2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_inside_top_level_2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..84d90fc
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_inside_top_level_2.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class A<T> {
+ A(T x);
+}
+
+main() {}
+var t1 = <A<int>>[new A(1)];
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart.textual_outline.expect
new file mode 100644
index 0000000..df0025f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart.textual_outline.expect
@@ -0,0 +1,24 @@
+library test;
+
+class F0 {
+ F0(List<int> a) {}
+}
+
+class F1 {
+ F1({List<int> a}) {}
+}
+
+class F2 {
+ F2(Iterable<int> a) {}
+}
+
+class F3 {
+ F3(Iterable<Iterable<int>> a) {}
+}
+
+class F4 {
+ F4({Iterable<Iterable<int>> a}) {}
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e349236
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+library test;
+
+class F0 {
+ F0(List<int> a) {}
+}
+
+class F1 {
+ F1({List<int> a}) {}
+}
+
+class F2 {
+ F2(Iterable<int> a) {}
+}
+
+class F3 {
+ F3(Iterable<Iterable<int>> a) {}
+}
+
+class F4 {
+ F4({Iterable<Iterable<int>> a}) {}
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart.textual_outline.expect
new file mode 100644
index 0000000..48d5e7a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+void f0(List<int> a) {}
+void f1({List<int> a}) {}
+void f2(Iterable<int> a) {}
+void f3(Iterable<Iterable<int>> a) {}
+void f4({Iterable<Iterable<int>> a}) {}
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1799ee7
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+main() {}
+void f0(List<int> a) {}
+void f1({List<int> a}) {}
+void f2(Iterable<int> a) {}
+void f3(Iterable<Iterable<int>> a) {}
+void f4({Iterable<Iterable<int>> a}) {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.textual_outline.expect
new file mode 100644
index 0000000..c66b28f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+typedef T Function2<S, T>(S x);
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..894e031
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+main() {}
+typedef T Function2<S, T>(S x);
+void test() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_function_of_t_using_the_t.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_on_function_of_t_using_the_t.dart.textual_outline.expect
new file mode 100644
index 0000000..c07c403
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_function_of_t_using_the_t.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+void main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_function_of_t_using_the_t.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_on_function_of_t_using_the_t.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c07c403
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_function_of_t_using_the_t.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+void main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_empty_list.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_empty_list.dart.textual_outline.expect
new file mode 100644
index 0000000..a13b45e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_empty_list.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+class F3<T> {
+ F3(Iterable<Iterable<T>> a) {}
+}
+
+class F4<T> {
+ F4({Iterable<Iterable<T>> a}) {}
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_empty_list.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_empty_list.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a13b45e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_empty_list.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+class F3<T> {
+ F3(Iterable<Iterable<T>> a) {}
+}
+
+class F4<T> {
+ F4({Iterable<Iterable<T>> a}) {}
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart.textual_outline.expect
new file mode 100644
index 0000000..3906f3d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart.textual_outline.expect
@@ -0,0 +1,24 @@
+library test;
+
+class F0<T> {
+ F0(List<T> a) {}
+}
+
+class F1<T> {
+ F1({List<T> a}) {}
+}
+
+class F2<T> {
+ F2(Iterable<T> a) {}
+}
+
+class F3<T> {
+ F3(Iterable<Iterable<T>> a) {}
+}
+
+class F4<T> {
+ F4({Iterable<Iterable<T>> a}) {}
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e9d27b1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+library test;
+
+class F0<T> {
+ F0(List<T> a) {}
+}
+
+class F1<T> {
+ F1({List<T> a}) {}
+}
+
+class F2<T> {
+ F2(Iterable<T> a) {}
+}
+
+class F3<T> {
+ F3(Iterable<Iterable<T>> a) {}
+}
+
+class F4<T> {
+ F4({Iterable<Iterable<T>> a}) {}
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.textual_outline.expect
new file mode 100644
index 0000000..a6bcf94
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..72a3ba0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.textual_outline.expect
new file mode 100644
index 0000000..8ed5bad
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.textual_outline.expect
@@ -0,0 +1,35 @@
+library test;
+
+class A<S, T> {
+ S x;
+ T y;
+ A(this.x, this.y);
+ A.named(this.x, this.y);
+}
+
+class B<S, T> extends A<T, S> {
+ B(S y, T x) : super(x, y);
+ B.named(S y, T x) : super.named(x, y);
+}
+
+class C<S> extends B<S, S> {
+ C(S a) : super(a, a);
+ C.named(S a) : super.named(a, a);
+}
+
+class D<S, T> extends B<T, int> {
+ D(T a) : super(a, 3);
+ D.named(T a) : super.named(a, 3);
+}
+
+class E<S, T> extends A<C<S>, T> {
+ E(T a) : super(null, a);
+}
+
+class F<S, T> extends A<S, T> {
+ F(S x, T y, {List<S> a, List<T> b}) : super(x, y);
+ F.named(S x, T y, [S a, T b]) : super(a, b);
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b73942e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,35 @@
+library test;
+
+class A<S, T> {
+ A(this.x, this.y);
+ A.named(this.x, this.y);
+ S x;
+ T y;
+}
+
+class B<S, T> extends A<T, S> {
+ B(S y, T x) : super(x, y);
+ B.named(S y, T x) : super.named(x, y);
+}
+
+class C<S> extends B<S, S> {
+ C(S a) : super(a, a);
+ C.named(S a) : super.named(a, a);
+}
+
+class D<S, T> extends B<T, int> {
+ D(T a) : super(a, 3);
+ D.named(T a) : super.named(a, 3);
+}
+
+class E<S, T> extends A<C<S>, T> {
+ E(T a) : super(null, a);
+}
+
+class F<S, T> extends A<S, T> {
+ F(S x, T y, {List<S> a, List<T> b}) : super(x, y);
+ F.named(S x, T y, [S a, T b]) : super(a, b);
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart.textual_outline.expect
new file mode 100644
index 0000000..428644a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+void foo([List<String> list1 = const [], List<String> list2 = const [42]]) {}
+void main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..428644a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+void foo([List<String> list1 = const [], List<String> list2 = const [42]]) {}
+void main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_if_value_types_match_context.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_if_value_types_match_context.dart.textual_outline.expect
new file mode 100644
index 0000000..96844fa
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_if_value_types_match_context.dart.textual_outline.expect
@@ -0,0 +1,28 @@
+library test;
+
+class DartType {}
+
+typedef void Asserter<T>(T type);
+typedef Asserter<T> AsserterBuilder<S, T>(S arg);
+Asserter<DartType> _isInt;
+Asserter<DartType> _isString;
+
+abstract class C {
+ static AsserterBuilder<List<Asserter<DartType>>, DartType> assertBOf;
+ static AsserterBuilder<List<Asserter<DartType>>, DartType> get assertCOf =>
+ null;
+ AsserterBuilder<List<Asserter<DartType>>, DartType> assertAOf;
+ AsserterBuilder<List<Asserter<DartType>>, DartType> get assertDOf;
+ method(AsserterBuilder<List<Asserter<DartType>>, DartType> assertEOf) {}
+}
+
+abstract class G<T> {
+ AsserterBuilder<List<Asserter<DartType>>, DartType> assertAOf;
+ AsserterBuilder<List<Asserter<DartType>>, DartType> get assertDOf;
+ method(AsserterBuilder<List<Asserter<DartType>>, DartType> assertEOf) {}
+}
+
+AsserterBuilder<List<Asserter<DartType>>, DartType> assertBOf;
+AsserterBuilder<List<Asserter<DartType>>, DartType> get assertCOf => null;
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_if_value_types_match_context.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_if_value_types_match_context.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..559999a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_if_value_types_match_context.dart.textual_outline_modelled.expect
@@ -0,0 +1,28 @@
+library test;
+
+Asserter<DartType> _isInt;
+Asserter<DartType> _isString;
+AsserterBuilder<List<Asserter<DartType>>, DartType> assertBOf;
+AsserterBuilder<List<Asserter<DartType>>, DartType> get assertCOf => null;
+
+abstract class C {
+ AsserterBuilder<List<Asserter<DartType>>, DartType> assertAOf;
+ AsserterBuilder<List<Asserter<DartType>>, DartType> get assertDOf;
+ method(AsserterBuilder<List<Asserter<DartType>>, DartType> assertEOf) {}
+ static AsserterBuilder<List<Asserter<DartType>>, DartType> assertBOf;
+ static AsserterBuilder<List<Asserter<DartType>>, DartType> get assertCOf =>
+ null;
+}
+
+abstract class G<T> {
+ AsserterBuilder<List<Asserter<DartType>>, DartType> assertAOf;
+ AsserterBuilder<List<Asserter<DartType>>, DartType> get assertDOf;
+ method(AsserterBuilder<List<Asserter<DartType>>, DartType> assertEOf) {}
+}
+
+class DartType {}
+
+main() {}
+test() {}
+typedef Asserter<T> AsserterBuilder<S, T>(S arg);
+typedef void Asserter<T>(T type);
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart.textual_outline.expect
new file mode 100644
index 0000000..423bbf0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+void foo(
+ [Map<int, String> m1 = const {1: "hello"},
+ Map<int, String> m2 = const {"hello": "world"}]) {}
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9e39c4b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+main() {}
+void foo(
+ [Map<int, String> m1 = const {1: "hello"},
+ Map<int, String> m2 = const {"hello": "world"}]) {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.textual_outline.expect b/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.textual_outline.expect
new file mode 100644
index 0000000..579e9aa
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+import 'dart:async';
+
+abstract class MyStream<T> extends Stream<T> {
+ factory MyStream() => null;
+}
+
+Stream<List<int>> foo() async* {}
+Iterable<Map<int, int>> bar() sync* {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ca60c6e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+import 'dart:async';
+
+Iterable<Map<int, int>> bar() sync* {}
+Stream<List<int>> foo() async* {}
+
+abstract class MyStream<T> extends Stream<T> {
+ factory MyStream() => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/dynamic_methods.dart.textual_outline.expect b/pkg/front_end/testcases/inference/dynamic_methods.dart.textual_outline.expect
new file mode 100644
index 0000000..d2690b8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/dynamic_methods.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class Foo {
+ int foo(int x) => x;
+}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/dynamic_methods.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/dynamic_methods.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..441f1e9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/dynamic_methods.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class Foo {
+ int foo(int x) => x;
+}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/field_initializer_context_explicit.dart.textual_outline.expect b/pkg/front_end/testcases/inference/field_initializer_context_explicit.dart.textual_outline.expect
new file mode 100644
index 0000000..5834483
--- /dev/null
+++ b/pkg/front_end/testcases/inference/field_initializer_context_explicit.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+T f<T>() => null;
+
+class C {
+ final int x;
+ C() : x = f();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/field_initializer_context_explicit.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/field_initializer_context_explicit.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c0625ce
--- /dev/null
+++ b/pkg/front_end/testcases/inference/field_initializer_context_explicit.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+T f<T>() => null;
+
+class C {
+ C() : x = f();
+ final int x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.textual_outline.expect b/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.textual_outline.expect
new file mode 100644
index 0000000..f06b5ed
--- /dev/null
+++ b/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+library test;
+
+T f<T>() => null;
+
+class C implements B {
+ final x;
+ C() : x = f();
+}
+
+abstract class B {
+ int get x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8c75d5e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+library test;
+
+T f<T>() => null;
+
+abstract class B {
+ int get x;
+}
+
+class C implements B {
+ C() : x = f();
+ final x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/field_initializer_context_this.dart.textual_outline.expect b/pkg/front_end/testcases/inference/field_initializer_context_this.dart.textual_outline.expect
new file mode 100644
index 0000000..b7af1b5
--- /dev/null
+++ b/pkg/front_end/testcases/inference/field_initializer_context_this.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+T f<T>() => null;
+
+class C {
+ final int x;
+ C() : this.x = f();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/field_initializer_context_this.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/field_initializer_context_this.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e1c779c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/field_initializer_context_this.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+T f<T>() => null;
+
+class C {
+ C() : this.x = f();
+ final int x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/field_initializer_parameter.dart.textual_outline.expect b/pkg/front_end/testcases/inference/field_initializer_parameter.dart.textual_outline.expect
new file mode 100644
index 0000000..94b8c9a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/field_initializer_parameter.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+T f<T>(T t) => t;
+
+class C {
+ final x;
+ C(int p) : x = f(p);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/field_initializer_parameter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/field_initializer_parameter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8596052
--- /dev/null
+++ b/pkg/front_end/testcases/inference/field_initializer_parameter.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+T f<T>(T t) => t;
+
+class C {
+ C(int p) : x = f(p);
+ final x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/field_refers_to_static_getter.dart.textual_outline.expect b/pkg/front_end/testcases/inference/field_refers_to_static_getter.dart.textual_outline.expect
new file mode 100644
index 0000000..77eff22
--- /dev/null
+++ b/pkg/front_end/testcases/inference/field_refers_to_static_getter.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C {
+ final x = _x;
+ static int get _x => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/field_refers_to_static_getter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/field_refers_to_static_getter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..77eff22
--- /dev/null
+++ b/pkg/front_end/testcases/inference/field_refers_to_static_getter.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C {
+ final x = _x;
+ static int get _x => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/field_refers_to_top_level_getter.dart.textual_outline.expect b/pkg/front_end/testcases/inference/field_refers_to_top_level_getter.dart.textual_outline.expect
new file mode 100644
index 0000000..66535ed
--- /dev/null
+++ b/pkg/front_end/testcases/inference/field_refers_to_top_level_getter.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C {
+ final x = y;
+}
+
+int get y => null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/field_refers_to_top_level_getter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/field_refers_to_top_level_getter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..66535ed
--- /dev/null
+++ b/pkg/front_end/testcases/inference/field_refers_to_top_level_getter.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C {
+ final x = y;
+}
+
+int get y => null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.textual_outline.expect b/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.textual_outline.expect
new file mode 100644
index 0000000..178286b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+test() async {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4791aa1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+test() async {}
diff --git a/pkg/front_end/testcases/inference/for_in_loop_promotion.dart.textual_outline.expect b/pkg/front_end/testcases/inference/for_in_loop_promotion.dart.textual_outline.expect
new file mode 100644
index 0000000..9d1fb80
--- /dev/null
+++ b/pkg/front_end/testcases/inference/for_in_loop_promotion.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+void test(List<num> nums) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/for_in_loop_promotion.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/for_in_loop_promotion.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d7c5b5b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/for_in_loop_promotion.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+void test(List<num> nums) {}
diff --git a/pkg/front_end/testcases/inference/for_loop_empty_condition.dart.textual_outline.expect b/pkg/front_end/testcases/inference/for_loop_empty_condition.dart.textual_outline.expect
new file mode 100644
index 0000000..a6bcf94
--- /dev/null
+++ b/pkg/front_end/testcases/inference/for_loop_empty_condition.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/for_loop_empty_condition.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/for_loop_empty_condition.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..72a3ba0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/for_loop_empty_condition.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/for_loop_initializer_expression.dart.textual_outline.expect b/pkg/front_end/testcases/inference/for_loop_initializer_expression.dart.textual_outline.expect
new file mode 100644
index 0000000..a6bcf94
--- /dev/null
+++ b/pkg/front_end/testcases/inference/for_loop_initializer_expression.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/for_loop_initializer_expression.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/for_loop_initializer_expression.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..72a3ba0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/for_loop_initializer_expression.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/for_loop_promotion.dart.textual_outline.expect b/pkg/front_end/testcases/inference/for_loop_promotion.dart.textual_outline.expect
new file mode 100644
index 0000000..a6bcf94
--- /dev/null
+++ b/pkg/front_end/testcases/inference/for_loop_promotion.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/for_loop_promotion.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/for_loop_promotion.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..72a3ba0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/for_loop_promotion.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/future_or_subtyping.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_or_subtyping.dart.textual_outline.expect
new file mode 100644
index 0000000..553900b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_or_subtyping.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+import 'dart:async';
+
+void add(int x) {}
+add2(int y) {}
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_or_subtyping.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_or_subtyping.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..98466bc
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_or_subtyping.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+import 'dart:async';
+
+add2(int y) {}
+main() {}
+test() {}
+void add(int x) {}
diff --git a/pkg/front_end/testcases/inference/future_then.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_then.dart.textual_outline.expect
new file mode 100644
index 0000000..646b6b8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value(T x) {}
+ dynamic noSuchMethod(invocation) => null;
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_then.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_then.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..46bfa3f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value(T x) {}
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+ dynamic noSuchMethod(invocation) => null;
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_then_2.dart.textual_outline.expect
new file mode 100644
index 0000000..646b6b8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_2.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value(T x) {}
+ dynamic noSuchMethod(invocation) => null;
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_then_2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..46bfa3f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_2.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value(T x) {}
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+ dynamic noSuchMethod(invocation) => null;
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_then_3.dart.textual_outline.expect
new file mode 100644
index 0000000..646b6b8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_3.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value(T x) {}
+ dynamic noSuchMethod(invocation) => null;
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_then_3.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..46bfa3f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_3.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value(T x) {}
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+ dynamic noSuchMethod(invocation) => null;
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/future_then_4.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_then_4.dart.textual_outline.expect
new file mode 100644
index 0000000..646b6b8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_4.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value(T x) {}
+ dynamic noSuchMethod(invocation) => null;
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_then_4.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_then_4.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..46bfa3f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_4.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value(T x) {}
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+ dynamic noSuchMethod(invocation) => null;
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/future_then_5.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_then_5.dart.textual_outline.expect
new file mode 100644
index 0000000..646b6b8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_5.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value(T x) {}
+ dynamic noSuchMethod(invocation) => null;
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_then_5.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_then_5.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..46bfa3f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_5.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value(T x) {}
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+ dynamic noSuchMethod(invocation) => null;
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/future_then_6.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_then_6.dart.textual_outline.expect
new file mode 100644
index 0000000..646b6b8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_6.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value(T x) {}
+ dynamic noSuchMethod(invocation) => null;
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_then_6.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_then_6.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..46bfa3f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_6.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value(T x) {}
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+ dynamic noSuchMethod(invocation) => null;
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_then_conditional.dart.textual_outline.expect
new file mode 100644
index 0000000..646b6b8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value(T x) {}
+ dynamic noSuchMethod(invocation) => null;
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_then_conditional.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..46bfa3f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value(T x) {}
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+ dynamic noSuchMethod(invocation) => null;
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.textual_outline.expect
new file mode 100644
index 0000000..646b6b8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value(T x) {}
+ dynamic noSuchMethod(invocation) => null;
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..46bfa3f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value(T x) {}
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+ dynamic noSuchMethod(invocation) => null;
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.textual_outline.expect
new file mode 100644
index 0000000..646b6b8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value(T x) {}
+ dynamic noSuchMethod(invocation) => null;
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..46bfa3f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value(T x) {}
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+ dynamic noSuchMethod(invocation) => null;
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.textual_outline.expect
new file mode 100644
index 0000000..646b6b8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value(T x) {}
+ dynamic noSuchMethod(invocation) => null;
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..46bfa3f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value(T x) {}
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+ dynamic noSuchMethod(invocation) => null;
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.textual_outline.expect
new file mode 100644
index 0000000..646b6b8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value(T x) {}
+ dynamic noSuchMethod(invocation) => null;
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..46bfa3f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value(T x) {}
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+ dynamic noSuchMethod(invocation) => null;
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.textual_outline.expect
new file mode 100644
index 0000000..646b6b8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value(T x) {}
+ dynamic noSuchMethod(invocation) => null;
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..46bfa3f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value(T x) {}
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+ dynamic noSuchMethod(invocation) => null;
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.textual_outline.expect
new file mode 100644
index 0000000..242deb6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+import 'dart:async';
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8318b63
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+import 'dart:async';
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/future_then_explicit_future.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_then_explicit_future.dart.textual_outline.expect
new file mode 100644
index 0000000..64e9564
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_explicit_future.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+import "dart:async";
+
+m1() {}
+m2() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_then_explicit_future.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_then_explicit_future.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..64e9564
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_explicit_future.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+import "dart:async";
+
+m1() {}
+m2() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_then_ifNull.dart.textual_outline.expect
new file mode 100644
index 0000000..646b6b8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_ifNull.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value(T x) {}
+ dynamic noSuchMethod(invocation) => null;
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_then_ifNull.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..46bfa3f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_ifNull.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value(T x) {}
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+ dynamic noSuchMethod(invocation) => null;
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/future_then_upwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_then_upwards.dart.textual_outline.expect
new file mode 100644
index 0000000..7170757
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_upwards.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value(T x) {}
+ dynamic noSuchMethod(invocation) => null;
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+void main() {}
+MyFuture foo() => new MyFuture<int>.value(1);
diff --git a/pkg/front_end/testcases/inference/future_then_upwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_then_upwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ca061ba
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_upwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+library test;
+
+import 'dart:async';
+
+MyFuture foo() => new MyFuture<int>.value(1);
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value(T x) {}
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+ dynamic noSuchMethod(invocation) => null;
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.textual_outline.expect
new file mode 100644
index 0000000..7170757
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value(T x) {}
+ dynamic noSuchMethod(invocation) => null;
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+void main() {}
+MyFuture foo() => new MyFuture<int>.value(1);
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ca061ba
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+library test;
+
+import 'dart:async';
+
+MyFuture foo() => new MyFuture<int>.value(1);
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value(T x) {}
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+ dynamic noSuchMethod(invocation) => null;
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.textual_outline.expect
new file mode 100644
index 0000000..50e61e9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value(T x) {}
+ dynamic noSuchMethod(invocation) => null;
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+void test() {}
+Future foo() => new Future<int>.value(1);
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..96a1287b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+import 'dart:async';
+
+Future foo() => new Future<int>.value(1);
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value(T x) {}
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+ dynamic noSuchMethod(invocation) => null;
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart.textual_outline.expect
new file mode 100644
index 0000000..242deb6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+import 'dart:async';
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8318b63
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+import 'dart:async';
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.textual_outline.expect
new file mode 100644
index 0000000..8c3a854
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value(x) {}
+ dynamic noSuchMethod(invocation) => null;
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+Future<int> g1(bool x) async {}
+Future<int> g2(bool x) async => x ? 42 : new Future.value(42);
+Future<int> g3(bool x) async {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c118a02
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+library test;
+
+import 'dart:async';
+
+Future<int> g1(bool x) async {}
+Future<int> g2(bool x) async => x ? 42 : new Future.value(42);
+Future<int> g3(bool x) async {}
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value(x) {}
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+ dynamic noSuchMethod(invocation) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.textual_outline.expect
new file mode 100644
index 0000000..159bf6d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value(x) {}
+ dynamic noSuchMethod(invocation) => null;
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+Future<int> g1(bool x) async {}
+Future<int> g2(bool x) async => x ? 42 : new MyFuture.value(42);
+Future<int> g3(bool x) async {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..13e1b1b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+library test;
+
+import 'dart:async';
+
+Future<int> g1(bool x) async {}
+Future<int> g2(bool x) async => x ? 42 : new MyFuture.value(42);
+Future<int> g3(bool x) async {}
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value(x) {}
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+ dynamic noSuchMethod(invocation) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_union_downwards.dart.textual_outline.expect
new file mode 100644
index 0000000..93f6f0d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value([x]) {}
+ dynamic noSuchMethod(invocation) => null;
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+MyFuture f;
+Future<int> t1 = f.then((_) => new Future.value('hi'));
+Future<List<int>> t2 = f.then((_) => [3]);
+Future<List<int>> g2() async {}
+Future<List<int>> g3() async {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_union_downwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ef4133f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+library test;
+
+import 'dart:async';
+
+Future<List<int>> g2() async {}
+Future<List<int>> g3() async {}
+Future<List<int>> t2 = f.then((_) => [3]);
+Future<int> t1 = f.then((_) => new Future.value('hi'));
+MyFuture f;
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value([x]) {}
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+ dynamic noSuchMethod(invocation) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.textual_outline.expect
new file mode 100644
index 0000000..5d93ae7
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value([x]) {}
+ dynamic noSuchMethod(invocation) => null;
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+MyFuture f;
+Future<int> t1 = f.then((_) => new MyFuture.value('hi'));
+Future<List<int>> t2 = f.then((_) => [3]);
+Future<List<int>> g2() async {}
+Future<List<int>> g3() async {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f0a80cf
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+library test;
+
+import 'dart:async';
+
+Future<List<int>> g2() async {}
+Future<List<int>> g3() async {}
+Future<List<int>> t2 = f.then((_) => [3]);
+Future<int> t1 = f.then((_) => new MyFuture.value('hi'));
+MyFuture f;
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value([x]) {}
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+ dynamic noSuchMethod(invocation) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.textual_outline.expect
new file mode 100644
index 0000000..b9a2d35
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value([x]) {}
+ dynamic noSuchMethod(invocation) => null;
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+Future f;
+Future<int> t1 = f.then((_) => new Future.value('hi'));
+Future<List<int>> t2 = f.then((_) => [3]);
+Future<List<int>> g2() async {}
+Future<List<int>> g3() async {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9307472
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+library test;
+
+import 'dart:async';
+
+Future f;
+Future<List<int>> g2() async {}
+Future<List<int>> g3() async {}
+Future<List<int>> t2 = f.then((_) => [3]);
+Future<int> t1 = f.then((_) => new Future.value('hi'));
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value([x]) {}
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+ dynamic noSuchMethod(invocation) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.textual_outline.expect
new file mode 100644
index 0000000..cf8d63e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+library test;
+
+import 'dart:async';
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value([x]) {}
+ dynamic noSuchMethod(invocation) => null;
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+}
+
+Future f;
+Future<int> t1 = f.then((_) => new MyFuture.value('hi'));
+Future<List<int>> t2 = f.then((_) => [3]);
+Future<List<int>> g2() async {}
+Future<List<int>> g3() async {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3d8b7c8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+library test;
+
+import 'dart:async';
+
+Future f;
+Future<List<int>> g2() async {}
+Future<List<int>> g3() async {}
+Future<List<int>> t2 = f.then((_) => [3]);
+Future<int> t1 = f.then((_) => new MyFuture.value('hi'));
+
+class MyFuture<T> implements Future<T> {
+ MyFuture() {}
+ MyFuture.value([x]) {}
+ MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
+ dynamic noSuchMethod(invocation) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.textual_outline.expect
new file mode 100644
index 0000000..ff812a4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+import 'dart:async';
+
+foo() async {}
+
+class A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..13d8da5
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+import 'dart:async';
+
+class A {}
+
+foo() async {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.textual_outline.expect
new file mode 100644
index 0000000..f2493de
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+import 'dart:async';
+
+T id<T>(T x) => x;
+test() async {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0b74ebd
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+import 'dart:async';
+
+T id<T>(T x) => x;
+main() {}
+test() async {}
diff --git a/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.textual_outline.expect b/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.textual_outline.expect
new file mode 100644
index 0000000..b625587
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+import 'dart:async';
+
+main() async {}
+
+class A {}
+
+class B extends A {}
+
+class C extends A {}
diff --git a/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0cb32a3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+import 'dart:async';
+
+class A {}
+
+class B extends A {}
+
+class C extends A {}
+
+main() async {}
diff --git a/pkg/front_end/testcases/inference/generator_closure.dart.textual_outline.expect b/pkg/front_end/testcases/inference/generator_closure.dart.textual_outline.expect
new file mode 100644
index 0000000..d7b3836
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generator_closure.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+import 'dart:async';
+
+void foo(Stream<int> Function() values) {}
+void main() {}
diff --git a/pkg/front_end/testcases/inference/generator_closure.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/generator_closure.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d7b3836
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generator_closure.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+import 'dart:async';
+
+void foo(Stream<int> Function() values) {}
+void main() {}
diff --git a/pkg/front_end/testcases/inference/generic_functions_return_typedef.dart.textual_outline.expect b/pkg/front_end/testcases/inference/generic_functions_return_typedef.dart.textual_outline.expect
new file mode 100644
index 0000000..7213e8e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_functions_return_typedef.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+typedef void ToValue<T>(T value);
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_functions_return_typedef.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/generic_functions_return_typedef.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..97bb62099
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_functions_return_typedef.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+typedef void ToValue<T>(T value);
diff --git a/pkg/front_end/testcases/inference/generic_methods_basic_downward_inference.dart.textual_outline.expect b/pkg/front_end/testcases/inference/generic_methods_basic_downward_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..c2ccf15
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_basic_downward_inference.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+T f<S, T>(S s) => null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_basic_downward_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/generic_methods_basic_downward_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c2ccf15
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_basic_downward_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+T f<S, T>(S s) => null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_correctly_recognize_generic_upper_bound.dart.textual_outline.expect b/pkg/front_end/testcases/inference/generic_methods_correctly_recognize_generic_upper_bound.dart.textual_outline.expect
new file mode 100644
index 0000000..c453bac
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_correctly_recognize_generic_upper_bound.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class Foo<T extends Pattern> {
+ U method<U extends T>(U u) => u;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_correctly_recognize_generic_upper_bound.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/generic_methods_correctly_recognize_generic_upper_bound.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c453bac
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_correctly_recognize_generic_upper_bound.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class Foo<T extends Pattern> {
+ U method<U extends T>(U u) => u;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart.textual_outline.expect b/pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart.textual_outline.expect
new file mode 100644
index 0000000..b914263
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+import 'dart:math';
+
+void printInt(int x) => print(x);
+void printDouble(double x) => print(x);
+num myMax(num x, num y) => max(x, y);
+f() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d493668
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+import 'dart:math';
+
+f() {}
+main() {}
+num myMax(num x, num y) => max(x, y);
+void printDouble(double x) => print(x);
+void printInt(int x) => print(x);
diff --git a/pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart.textual_outline.expect b/pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart.textual_outline.expect
new file mode 100644
index 0000000..2f8aafa
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C {
+ T m<T>(T x) => x;
+}
+
+class D extends C {
+ m(x) => x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2f8aafa
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C {
+ T m<T>(T x) => x;
+}
+
+class D extends C {
+ m(x) => x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_downwards_inference_affects_arguments.dart.textual_outline.expect b/pkg/front_end/testcases/inference/generic_methods_downwards_inference_affects_arguments.dart.textual_outline.expect
new file mode 100644
index 0000000..f93fc4f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_downwards_inference_affects_arguments.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+T f<T>(List<T> s) => null;
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_downwards_inference_affects_arguments.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/generic_methods_downwards_inference_affects_arguments.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d8caec4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_downwards_inference_affects_arguments.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+T f<T>(List<T> s) => null;
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_downwards_inference_fold.dart.textual_outline.expect b/pkg/front_end/testcases/inference/generic_methods_downwards_inference_fold.dart.textual_outline.expect
new file mode 100644
index 0000000..0fedf11
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_downwards_inference_fold.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+void test() {}
+void functionExpressionInvocation() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_downwards_inference_fold.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/generic_methods_downwards_inference_fold.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fbb56e2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_downwards_inference_fold.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+main() {}
+void functionExpressionInvocation() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart.textual_outline.expect b/pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart.textual_outline.expect
new file mode 100644
index 0000000..9964182
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+class C {
+ m(x) => x;
+ dynamic g(int x) => x;
+}
+
+class D extends C {
+ T m<T>(T x) => x;
+ T g<T>(T x) => x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c3f4d33
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+class C {
+ dynamic g(int x) => x;
+ m(x) => x;
+}
+
+class D extends C {
+ T g<T>(T x) => x;
+ T m<T>(T x) => x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.textual_outline.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.textual_outline.expect
new file mode 100644
index 0000000..9702395
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+class C<T> extends D<T> {
+ f<U>(x) {}
+}
+
+class D<T> {
+ F<U> f<U>(U u) => null;
+}
+
+typedef void F<V>(V v);
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..445c8d6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+class C<T> extends D<T> {
+ f<U>(x) {}
+}
+
+class D<T> {
+ F<U> f<U>(U u) => null;
+}
+
+main() {}
+typedef void F<V>(V v);
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.textual_outline.expect
new file mode 100644
index 0000000..7bcb050
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+class C<T> extends D<T> {
+ f<U>(g) => null;
+}
+
+abstract class D<T> {
+ void f<U>(G<U> g);
+}
+
+typedef List<V> G<V>();
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6958c93
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+abstract class D<T> {
+ void f<U>(G<U> g);
+}
+
+class C<T> extends D<T> {
+ f<U>(g) => null;
+}
+
+main() {}
+typedef List<V> G<V>();
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_return_type.dart.textual_outline.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_return_type.dart.textual_outline.expect
new file mode 100644
index 0000000..99aa0ee
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_return_type.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+class C<T> extends D<T> {
+ f<U>(x) {}
+}
+
+class D<T> {
+ F<U> f<U>(U u) => null;
+}
+
+typedef V F<V>();
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_return_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_return_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2fedb57
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_return_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+class C<T> extends D<T> {
+ f<U>(x) {}
+}
+
+class D<T> {
+ F<U> f<U>(U u) => null;
+}
+
+main() {}
+typedef V F<V>();
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.textual_outline.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.textual_outline.expect
new file mode 100644
index 0000000..3271c03
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.textual_outline.expect
@@ -0,0 +1,25 @@
+library test;
+
+import 'dart:math' as math;
+import 'dart:math' show min;
+
+class C {
+ T m<T extends num>(T x, T y) => null;
+}
+
+test() {}
+void takeIII(int fn(int a, int b)) {}
+void takeDDD(double fn(double a, double b)) {}
+void takeIDI(int fn(double a, int b)) {}
+void takeDID(double fn(int a, double b)) {}
+void takeIDN(num fn(double a, int b)) {}
+void takeDIN(num fn(int a, double b)) {}
+void takeIIN(num fn(int a, int b)) {}
+void takeDDN(num fn(double a, double b)) {}
+void takeNNN(num fn(num a, num b)) {}
+void takeOON(num fn(Object a, Object b)) {}
+void takeOOO(num fn(Object a, Object b)) {}
+void takeOOI(int fn(Object a, Object b)) {}
+void takeIIO(Object fn(int a, int b)) {}
+void takeDDO(Object fn(double a, double b)) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ec53965
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.textual_outline_modelled.expect
@@ -0,0 +1,25 @@
+library test;
+
+import 'dart:math' as math;
+import 'dart:math' show min;
+
+class C {
+ T m<T extends num>(T x, T y) => null;
+}
+
+main() {}
+test() {}
+void takeDDD(double fn(double a, double b)) {}
+void takeDDN(num fn(double a, double b)) {}
+void takeDDO(Object fn(double a, double b)) {}
+void takeDID(double fn(int a, double b)) {}
+void takeDIN(num fn(int a, double b)) {}
+void takeIDI(int fn(double a, int b)) {}
+void takeIDN(num fn(double a, int b)) {}
+void takeIII(int fn(int a, int b)) {}
+void takeIIN(num fn(int a, int b)) {}
+void takeIIO(Object fn(int a, int b)) {}
+void takeNNN(num fn(num a, num b)) {}
+void takeOOI(int fn(Object a, Object b)) {}
+void takeOON(num fn(Object a, Object b)) {}
+void takeOOO(num fn(Object a, Object b)) {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_method_type.dart.textual_outline.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_method_type.dart.textual_outline.expect
new file mode 100644
index 0000000..6dbee2c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_method_type.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C {
+ T m<T>(T x) => x;
+}
+
+class D extends C {
+ m<S>(x) => x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_method_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_method_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6dbee2c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_method_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C {
+ T m<T>(T x) => x;
+}
+
+class D extends C {
+ m<S>(x) => x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart.textual_outline.expect b/pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart.textual_outline.expect
new file mode 100644
index 0000000..7454c6f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+import 'dart:_foreign_helper' show JS;
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..482fa81
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+import 'dart:_foreign_helper' show JS;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_inference_error.dart.textual_outline.expect b/pkg/front_end/testcases/inference/generic_methods_inference_error.dart.textual_outline.expect
new file mode 100644
index 0000000..e710694
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_inference_error.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+void f() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_inference_error.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/generic_methods_inference_error.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..42c4800
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_inference_error.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+void f() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.textual_outline.expect b/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.textual_outline.expect
new file mode 100644
index 0000000..649c05e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+import 'dart:async';
+
+Future<int> make(int x) => (new Future(() => x));
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..67fe832
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+import 'dart:async';
+
+Future<int> make(int x) => (new Future(() => x));
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_nested_generic_instantiation.dart.textual_outline.expect b/pkg/front_end/testcases/inference/generic_methods_nested_generic_instantiation.dart.textual_outline.expect
new file mode 100644
index 0000000..5998d2c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_nested_generic_instantiation.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:math' as math;
+
+class Trace {
+ List<Frame> frames = [];
+}
+
+class Frame {
+ String location = '';
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_nested_generic_instantiation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/generic_methods_nested_generic_instantiation.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2248ecd
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_nested_generic_instantiation.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'dart:math' as math;
+
+class Frame {
+ String location = '';
+}
+
+class Trace {
+ List<Frame> frames = [];
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_uses_greatest_lower_bound.dart.textual_outline.expect b/pkg/front_end/testcases/inference/generic_methods_uses_greatest_lower_bound.dart.textual_outline.expect
new file mode 100644
index 0000000..299707a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_uses_greatest_lower_bound.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+typedef Iterable<num> F(int x);
+typedef List<int> G(double x);
+T generic<T>(a(T _), b(T _)) => null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_uses_greatest_lower_bound.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/generic_methods_uses_greatest_lower_bound.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ecd0b24
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_uses_greatest_lower_bound.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+T generic<T>(a(T _), b(T _)) => null;
+main() {}
+typedef Iterable<num> F(int x);
+typedef List<int> G(double x);
diff --git a/pkg/front_end/testcases/inference/greatest_closure_multiple_params.dart.textual_outline.expect b/pkg/front_end/testcases/inference/greatest_closure_multiple_params.dart.textual_outline.expect
new file mode 100644
index 0000000..f36e1a9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/greatest_closure_multiple_params.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+abstract class C<E> {
+ void sort([int compare(E a, E b)]) {}
+ static int _compareAny(a, b) {}
+ static void sort2<E>(C<E> a, int compare(E a, E b)) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/greatest_closure_multiple_params.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/greatest_closure_multiple_params.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..928adb6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/greatest_closure_multiple_params.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+abstract class C<E> {
+ static int _compareAny(a, b) {}
+ static void sort2<E>(C<E> a, int compare(E a, E b)) {}
+ void sort([int compare(E a, E b)]) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/inconsistent_overrides.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inconsistent_overrides.dart.textual_outline.expect
new file mode 100644
index 0000000..67da6aa
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inconsistent_overrides.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+library test;
+
+class A {
+ A f(A x, {A y}) {}
+ A g(A x, {A y}) {}
+ A h(A x, {A y}) {}
+}
+
+class B extends A implements I {
+ f(x, {y}) {}
+ g(x, {y}) {}
+ h(x, {y}) {}
+}
+
+class I {
+ I f(I x, {I y}) {}
+ A g(I x, {I y}) {}
+ A h(A x, {I y}) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/inconsistent_overrides.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inconsistent_overrides.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4c44599
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inconsistent_overrides.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+library test;
+
+class A {
+ A f(A x, {A y}) {}
+ A g(A x, {A y}) {}
+ A h(A x, {A y}) {}
+}
+
+class B extends A implements I {
+ f(x, {y}) {}
+ g(x, {y}) {}
+ h(x, {y}) {}
+}
+
+class I {
+ A g(I x, {I y}) {}
+ A h(A x, {I y}) {}
+ I f(I x, {I y}) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.textual_outline.expect b/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.textual_outline.expect
new file mode 100644
index 0000000..71f35b9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+class C {
+ dynamic operator []=(dynamic index, dynamic value) {}
+}
+
+abstract class I {
+ void operator []=(dynamic index, dynamic value) {}
+}
+
+class D extends C implements I {
+ operator []=(dynamic index, dynamic value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d950bce
--- /dev/null
+++ b/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+abstract class I {
+ void operator []=(dynamic index, dynamic value) {}
+}
+
+class C {
+ dynamic operator []=(dynamic index, dynamic value) {}
+}
+
+class D extends C implements I {
+ operator []=(dynamic index, dynamic value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.textual_outline.expect
new file mode 100644
index 0000000..5b865ba
--- /dev/null
+++ b/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+class C {
+ dynamic operator []=(int index, dynamic value) {}
+}
+
+abstract class I {
+ void operator []=(int index, dynamic value) {}
+}
+
+class D extends C implements I {
+ operator []=(int index, value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..700f73a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+abstract class I {
+ void operator []=(int index, dynamic value) {}
+}
+
+class C {
+ dynamic operator []=(int index, dynamic value) {}
+}
+
+class D extends C implements I {
+ operator []=(int index, value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_accessor_from_later_inferred_field.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_accessor_from_later_inferred_field.dart.textual_outline.expect
new file mode 100644
index 0000000..e8e8fb2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_accessor_from_later_inferred_field.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+class A implements B {
+ get x => f();
+ void set x(value) {}
+}
+
+class B {
+ var x = 0;
+}
+
+dynamic f() => null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_accessor_from_later_inferred_field.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_accessor_from_later_inferred_field.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e8e8fb2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_accessor_from_later_inferred_field.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+class A implements B {
+ get x => f();
+ void set x(value) {}
+}
+
+class B {
+ var x = 0;
+}
+
+dynamic f() => null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_implicit_this.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this.dart.textual_outline.expect
new file mode 100644
index 0000000..cce1286
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+library test;
+
+class A {}
+
+class B extends A {
+ A operator +(C v) => null;
+ B operator -(int i) => null;
+ B operator *(B v) => null;
+ C operator &(A v) => null;
+}
+
+class C extends B {}
+
+T f<T>() => null;
+
+class Test {
+ B member;
+ void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_implicit_this.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fedf127
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+library test;
+
+T f<T>() => null;
+
+class A {}
+
+class B extends A {
+ A operator +(C v) => null;
+ B operator *(B v) => null;
+ B operator -(int i) => null;
+ C operator &(A v) => null;
+}
+
+class C extends B {}
+
+class Test {
+ B member;
+ void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_implicit_this_upwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this_upwards.dart.textual_outline.expect
new file mode 100644
index 0000000..5aea77f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this_upwards.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+library test;
+
+int getInt() => 0;
+num getNum() => 0;
+double getDouble() => 0.0;
+
+class Test1 {
+ int t;
+ void test() {}
+}
+
+class Test2 {
+ num t;
+ void test() {}
+}
+
+class Test3 {
+ double t;
+ void test3() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_implicit_this_upwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this_upwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c07ae2b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this_upwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+library test;
+
+class Test1 {
+ int t;
+ void test() {}
+}
+
+class Test2 {
+ num t;
+ void test() {}
+}
+
+class Test3 {
+ double t;
+ void test3() {}
+}
+
+double getDouble() => 0.0;
+int getInt() => 0;
+main() {}
+num getNum() => 0;
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_index_full.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_assign_to_index_full.dart.textual_outline.expect
new file mode 100644
index 0000000..b37e03c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_index_full.dart.textual_outline.expect
@@ -0,0 +1,24 @@
+library test;
+
+class Index {}
+
+class A {}
+
+class B extends A {
+ A operator +(C v) => null;
+ B operator -(int i) => null;
+ B operator *(B v) => null;
+ C operator &(A v) => null;
+}
+
+class C extends B {}
+
+T f<T>() => null;
+
+class Test {
+ B operator [](Index i) => null;
+ void operator []=(Index i, B v) {}
+ void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_index_full.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_assign_to_index_full.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e02d004
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_index_full.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+library test;
+
+T f<T>() => null;
+
+class A {}
+
+class B extends A {
+ A operator +(C v) => null;
+ B operator *(B v) => null;
+ B operator -(int i) => null;
+ C operator &(A v) => null;
+}
+
+class C extends B {}
+
+class Index {}
+
+class Test {
+ B operator [](Index i) => null;
+ void operator []=(Index i, B v) {}
+ void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_index_super.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_assign_to_index_super.dart.textual_outline.expect
new file mode 100644
index 0000000..0082739
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_index_super.dart.textual_outline.expect
@@ -0,0 +1,27 @@
+library test;
+
+class Index {}
+
+class A {}
+
+class B extends A {
+ A operator +(C v) => null;
+ B operator -(int i) => null;
+ B operator *(B v) => null;
+ C operator &(A v) => null;
+}
+
+class C extends B {}
+
+T f<T>() => null;
+
+class Base {
+ B operator [](Index i) => null;
+ void operator []=(Index i, B v) {}
+}
+
+class Test extends Base {
+ void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_index_super.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_assign_to_index_super.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3153d49
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_index_super.dart.textual_outline_modelled.expect
@@ -0,0 +1,27 @@
+library test;
+
+T f<T>() => null;
+
+class A {}
+
+class B extends A {
+ A operator +(C v) => null;
+ B operator *(B v) => null;
+ B operator -(int i) => null;
+ C operator &(A v) => null;
+}
+
+class Base {
+ B operator [](Index i) => null;
+ void operator []=(Index i, B v) {}
+}
+
+class C extends B {}
+
+class Index {}
+
+class Test extends Base {
+ void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_index_this.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_assign_to_index_this.dart.textual_outline.expect
new file mode 100644
index 0000000..b37e03c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_index_this.dart.textual_outline.expect
@@ -0,0 +1,24 @@
+library test;
+
+class Index {}
+
+class A {}
+
+class B extends A {
+ A operator +(C v) => null;
+ B operator -(int i) => null;
+ B operator *(B v) => null;
+ C operator &(A v) => null;
+}
+
+class C extends B {}
+
+T f<T>() => null;
+
+class Test {
+ B operator [](Index i) => null;
+ void operator []=(Index i, B v) {}
+ void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_index_this.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_assign_to_index_this.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e02d004
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_index_this.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+library test;
+
+T f<T>() => null;
+
+class A {}
+
+class B extends A {
+ A operator +(C v) => null;
+ B operator *(B v) => null;
+ B operator -(int i) => null;
+ C operator &(A v) => null;
+}
+
+class C extends B {}
+
+class Index {}
+
+class Test {
+ B operator [](Index i) => null;
+ void operator []=(Index i, B v) {}
+ void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_local.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_assign_to_local.dart.textual_outline.expect
new file mode 100644
index 0000000..54818ba
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_local.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+library test;
+
+class A {}
+
+class B extends A {
+ A operator +(C v) => null;
+ B operator -(int i) => null;
+ B operator *(B v) => null;
+ C operator &(A v) => null;
+}
+
+class C extends B {}
+
+T f<T>() => null;
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_local.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_assign_to_local.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..370d98d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_local.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+library test;
+
+T f<T>() => null;
+
+class A {}
+
+class B extends A {
+ A operator +(C v) => null;
+ B operator *(B v) => null;
+ B operator -(int i) => null;
+ C operator &(A v) => null;
+}
+
+class C extends B {}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart.textual_outline.expect
new file mode 100644
index 0000000..d9659ac
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+int getInt() => 0;
+num getNum() => 0;
+double getDouble() => 0.0;
+void test1(int t) {}
+void test2(num t) {}
+void test3(double t) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f01f8e9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+double getDouble() => 0.0;
+int getInt() => 0;
+main() {}
+num getNum() => 0;
+void test1(int t) {}
+void test2(num t) {}
+void test3(double t) {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_full.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_full.dart.textual_outline.expect
new file mode 100644
index 0000000..f1916a0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_full.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+library test;
+
+class A {}
+
+class B extends A {
+ A operator +(C v) => null;
+ B operator -(int i) => null;
+ B operator *(B v) => null;
+ C operator &(A v) => null;
+}
+
+class C extends B {}
+
+T f<T>() => null;
+
+class Test {
+ B member;
+ static void test(Test t) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_full.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_full.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1ddd4b1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_full.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+library test;
+
+T f<T>() => null;
+
+class A {}
+
+class B extends A {
+ A operator +(C v) => null;
+ B operator *(B v) => null;
+ B operator -(int i) => null;
+ C operator &(A v) => null;
+}
+
+class C extends B {}
+
+class Test {
+ B member;
+ static void test(Test t) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart.textual_outline.expect
new file mode 100644
index 0000000..f1916a0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+library test;
+
+class A {}
+
+class B extends A {
+ A operator +(C v) => null;
+ B operator -(int i) => null;
+ B operator *(B v) => null;
+ C operator &(A v) => null;
+}
+
+class C extends B {}
+
+T f<T>() => null;
+
+class Test {
+ B member;
+ static void test(Test t) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1ddd4b1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+library test;
+
+T f<T>() => null;
+
+class A {}
+
+class B extends A {
+ A operator +(C v) => null;
+ B operator *(B v) => null;
+ B operator -(int i) => null;
+ C operator &(A v) => null;
+}
+
+class C extends B {}
+
+class Test {
+ B member;
+ static void test(Test t) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart.textual_outline.expect
new file mode 100644
index 0000000..0757142
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+library test;
+
+int getInt() => 0;
+num getNum() => 0;
+double getDouble() => 0.0;
+
+class Test1 {
+ int prop;
+ static void test(Test1 t) {}
+}
+
+class Test2 {
+ num prop;
+ static void test(Test2 t) {}
+}
+
+class Test3 {
+ double prop;
+ static void test3(Test3 t) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..265e693
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+library test;
+
+class Test1 {
+ int prop;
+ static void test(Test1 t) {}
+}
+
+class Test2 {
+ num prop;
+ static void test(Test2 t) {}
+}
+
+class Test3 {
+ double prop;
+ static void test3(Test3 t) {}
+}
+
+double getDouble() => 0.0;
+int getInt() => 0;
+main() {}
+num getNum() => 0;
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_super.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_super.dart.textual_outline.expect
new file mode 100644
index 0000000..2d1227e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_super.dart.textual_outline.expect
@@ -0,0 +1,24 @@
+library test;
+
+class A {}
+
+class B extends A {
+ A operator +(C v) => null;
+ B operator -(int i) => null;
+ B operator *(B v) => null;
+ C operator &(A v) => null;
+}
+
+class C extends B {}
+
+T f<T>() => null;
+
+class Base {
+ B member;
+}
+
+class Test extends Base {
+ void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_super.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_super.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cdf4959
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_super.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+library test;
+
+T f<T>() => null;
+
+class A {}
+
+class B extends A {
+ A operator +(C v) => null;
+ B operator *(B v) => null;
+ B operator -(int i) => null;
+ C operator &(A v) => null;
+}
+
+class Base {
+ B member;
+}
+
+class C extends B {}
+
+class Test extends Base {
+ void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_super_upwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_super_upwards.dart.textual_outline.expect
new file mode 100644
index 0000000..31af0c8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_super_upwards.dart.textual_outline.expect
@@ -0,0 +1,25 @@
+library test;
+
+int getInt() => 0;
+num getNum() => 0;
+double getDouble() => 0.0;
+
+class Base {
+ int intProp;
+ num numProp;
+ double doubleProp;
+}
+
+class Test1 extends Base {
+ void test() {}
+}
+
+class Test2 extends Base {
+ void test() {}
+}
+
+class Test3 extends Base {
+ void test3() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_super_upwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_super_upwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5d5e219
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_super_upwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+library test;
+
+class Base {
+ double doubleProp;
+ int intProp;
+ num numProp;
+}
+
+class Test1 extends Base {
+ void test() {}
+}
+
+class Test2 extends Base {
+ void test() {}
+}
+
+class Test3 extends Base {
+ void test3() {}
+}
+
+double getDouble() => 0.0;
+int getInt() => 0;
+main() {}
+num getNum() => 0;
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_upwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_upwards.dart.textual_outline.expect
new file mode 100644
index 0000000..0757142
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_upwards.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+library test;
+
+int getInt() => 0;
+num getNum() => 0;
+double getDouble() => 0.0;
+
+class Test1 {
+ int prop;
+ static void test(Test1 t) {}
+}
+
+class Test2 {
+ num prop;
+ static void test(Test2 t) {}
+}
+
+class Test3 {
+ double prop;
+ static void test3(Test3 t) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_upwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_upwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..265e693
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_upwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+library test;
+
+class Test1 {
+ int prop;
+ static void test(Test1 t) {}
+}
+
+class Test2 {
+ num prop;
+ static void test(Test2 t) {}
+}
+
+class Test3 {
+ double prop;
+ static void test3(Test3 t) {}
+}
+
+double getDouble() => 0.0;
+int getInt() => 0;
+main() {}
+num getNum() => 0;
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_ref.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_assign_to_ref.dart.textual_outline.expect
new file mode 100644
index 0000000..6566843
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_ref.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+class A {
+ int f;
+}
+
+A a = new A();
+var c = 0;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_ref.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_assign_to_ref.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1170f43
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_ref.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+A a = new A();
+
+class A {
+ int f;
+}
+
+main() {}
+var c = 0;
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_static.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_assign_to_static.dart.textual_outline.expect
new file mode 100644
index 0000000..3ee6268
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_static.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+library test;
+
+class A {}
+
+class B extends A {
+ A operator +(C v) => null;
+ B operator -(int i) => null;
+ B operator *(B v) => null;
+ C operator &(A v) => null;
+ static B staticVariable;
+}
+
+class C extends B {}
+
+T f<T>() => null;
+B topLevelVariable;
+void test_topLevelVariable() {}
+void test_staticVariable() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_static.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_assign_to_static.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..667b734
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_static.dart.textual_outline_modelled.expect
@@ -0,0 +1,20 @@
+library test;
+
+B topLevelVariable;
+T f<T>() => null;
+
+class A {}
+
+class B extends A {
+ A operator +(C v) => null;
+ B operator *(B v) => null;
+ B operator -(int i) => null;
+ C operator &(A v) => null;
+ static B staticVariable;
+}
+
+class C extends B {}
+
+main() {}
+void test_staticVariable() {}
+void test_topLevelVariable() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_static_upwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_assign_to_static_upwards.dart.textual_outline.expect
new file mode 100644
index 0000000..13362e8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_static_upwards.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+int getInt() => 0;
+num getNum() => 0;
+double getDouble() => 0.0;
+int topLevelInt;
+num topLevelNum;
+double topLevelDouble;
+void test1() {}
+void test2() {}
+void test3() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_static_upwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_assign_to_static_upwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2b31b13
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_static_upwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+double getDouble() => 0.0;
+double topLevelDouble;
+int getInt() => 0;
+int topLevelInt;
+main() {}
+num getNum() => 0;
+num topLevelNum;
+void test1() {}
+void test2() {}
+void test3() {}
diff --git a/pkg/front_end/testcases/inference/infer_binary_custom.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_binary_custom.dart.textual_outline.expect
new file mode 100644
index 0000000..80ca252
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_binary_custom.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class A {
+ int operator +(other) => 1;
+ double operator -(other) => 2.0;
+}
+
+var v_add = new A() + 'foo';
+var v_minus = new A() - 'bar';
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_binary_custom.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_binary_custom.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0b2556e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_binary_custom.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class A {
+ double operator -(other) => 2.0;
+ int operator +(other) => 1;
+}
+
+main() {}
+var v_add = new A() + 'foo';
+var v_minus = new A() - 'bar';
diff --git a/pkg/front_end/testcases/inference/infer_binary_double_double.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_binary_double_double.dart.textual_outline.expect
new file mode 100644
index 0000000..afb98b1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_binary_double_double.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+var a_equal = 1.0 == 2.0;
+var a_notEqual = 1.0 != 2.0;
+var a_add = 1.0 + 2.0;
+var a_subtract = 1.0 - 2.0;
+var a_multiply = 1.0 * 2.0;
+var a_divide = 1.0 / 2.0;
+var a_floorDivide = 1.0 ~/ 2.0;
+var a_greater = 1.0 > 2.0;
+var a_less = 1.0 < 2.0;
+var a_greaterEqual = 1.0 >= 2.0;
+var a_lessEqual = 1.0 <= 2.0;
+var a_modulo = 1.0 % 2.0;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_binary_double_double.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_binary_double_double.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6ca4cc2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_binary_double_double.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+main() {}
+var a_add = 1.0 + 2.0;
+var a_divide = 1.0 / 2.0;
+var a_equal = 1.0 == 2.0;
+var a_floorDivide = 1.0 ~/ 2.0;
+var a_greater = 1.0 > 2.0;
+var a_greaterEqual = 1.0 >= 2.0;
+var a_less = 1.0 < 2.0;
+var a_lessEqual = 1.0 <= 2.0;
+var a_modulo = 1.0 % 2.0;
+var a_multiply = 1.0 * 2.0;
+var a_notEqual = 1.0 != 2.0;
+var a_subtract = 1.0 - 2.0;
diff --git a/pkg/front_end/testcases/inference/infer_binary_double_int.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_binary_double_int.dart.textual_outline.expect
new file mode 100644
index 0000000..5b6dace
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_binary_double_int.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+var a_equal = 1.0 == 2;
+var a_notEqual = 1.0 != 2;
+var a_add = 1.0 + 2;
+var a_subtract = 1.0 - 2;
+var a_multiply = 1.0 * 2;
+var a_divide = 1.0 / 2;
+var a_floorDivide = 1.0 ~/ 2;
+var a_greater = 1.0 > 2;
+var a_less = 1.0 < 2;
+var a_greaterEqual = 1.0 >= 2;
+var a_lessEqual = 1.0 <= 2;
+var a_modulo = 1.0 % 2;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_binary_double_int.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_binary_double_int.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e8ac0d0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_binary_double_int.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+main() {}
+var a_add = 1.0 + 2;
+var a_divide = 1.0 / 2;
+var a_equal = 1.0 == 2;
+var a_floorDivide = 1.0 ~/ 2;
+var a_greater = 1.0 > 2;
+var a_greaterEqual = 1.0 >= 2;
+var a_less = 1.0 < 2;
+var a_lessEqual = 1.0 <= 2;
+var a_modulo = 1.0 % 2;
+var a_multiply = 1.0 * 2;
+var a_notEqual = 1.0 != 2;
+var a_subtract = 1.0 - 2;
diff --git a/pkg/front_end/testcases/inference/infer_binary_int_double.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_binary_int_double.dart.textual_outline.expect
new file mode 100644
index 0000000..f4d00de
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_binary_int_double.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+var a_equal = 1 == 2.0;
+var a_notEqual = 1 != 2.0;
+var a_add = 1 + 2.0;
+var a_subtract = 1 - 2.0;
+var a_multiply = 1 * 2.0;
+var a_divide = 1 / 2.0;
+var a_floorDivide = 1 ~/ 2.0;
+var a_greater = 1 > 2.0;
+var a_less = 1 < 2.0;
+var a_greaterEqual = 1 >= 2.0;
+var a_lessEqual = 1 <= 2.0;
+var a_modulo = 1 % 2.0;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_binary_int_double.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_binary_int_double.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ba59e589
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_binary_int_double.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+main() {}
+var a_add = 1 + 2.0;
+var a_divide = 1 / 2.0;
+var a_equal = 1 == 2.0;
+var a_floorDivide = 1 ~/ 2.0;
+var a_greater = 1 > 2.0;
+var a_greaterEqual = 1 >= 2.0;
+var a_less = 1 < 2.0;
+var a_lessEqual = 1 <= 2.0;
+var a_modulo = 1 % 2.0;
+var a_multiply = 1 * 2.0;
+var a_notEqual = 1 != 2.0;
+var a_subtract = 1 - 2.0;
diff --git a/pkg/front_end/testcases/inference/infer_binary_int_int.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_binary_int_int.dart.textual_outline.expect
new file mode 100644
index 0000000..f139d16
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_binary_int_int.dart.textual_outline.expect
@@ -0,0 +1,20 @@
+library test;
+
+var a_equal = 1 == 2;
+var a_notEqual = 1 != 2;
+var a_bitXor = 1 ^ 2;
+var a_bitAnd = 1 & 2;
+var a_bitOr = 1 | 2;
+var a_bitShiftRight = 1 >> 2;
+var a_bitShiftLeft = 1 << 2;
+var a_add = 1 + 2;
+var a_subtract = 1 - 2;
+var a_multiply = 1 * 2;
+var a_divide = 1 / 2;
+var a_floorDivide = 1 ~/ 2;
+var a_greater = 1 > 2;
+var a_less = 1 < 2;
+var a_greaterEqual = 1 >= 2;
+var a_lessEqual = 1 <= 2;
+var a_modulo = 1 % 2;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_binary_int_int.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_binary_int_int.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..dae8595
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_binary_int_int.dart.textual_outline_modelled.expect
@@ -0,0 +1,20 @@
+library test;
+
+main() {}
+var a_add = 1 + 2;
+var a_bitAnd = 1 & 2;
+var a_bitOr = 1 | 2;
+var a_bitShiftLeft = 1 << 2;
+var a_bitShiftRight = 1 >> 2;
+var a_bitXor = 1 ^ 2;
+var a_divide = 1 / 2;
+var a_equal = 1 == 2;
+var a_floorDivide = 1 ~/ 2;
+var a_greater = 1 > 2;
+var a_greaterEqual = 1 >= 2;
+var a_less = 1 < 2;
+var a_lessEqual = 1 <= 2;
+var a_modulo = 1 % 2;
+var a_multiply = 1 * 2;
+var a_notEqual = 1 != 2;
+var a_subtract = 1 - 2;
diff --git a/pkg/front_end/testcases/inference/infer_conditional.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_conditional.dart.textual_outline.expect
new file mode 100644
index 0000000..49f6015
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_conditional.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+var a = 1 == 2 ? 1 : 2.0;
+var b = 1 == 2 ? 1.0 : 2;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_conditional.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_conditional.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..da56220
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_conditional.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+main() {}
+var a = 1 == 2 ? 1 : 2.0;
+var b = 1 == 2 ? 1.0 : 2;
diff --git a/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.textual_outline.expect
new file mode 100644
index 0000000..e7967d4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+import 'infer_consts_transitively_2_a.dart';
+
+const m1 = a1;
+const m2 = a2;
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e7967d4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+import 'infer_consts_transitively_2_a.dart';
+
+const m1 = a1;
+const m2 = a2;
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.textual_outline.expect
new file mode 100644
index 0000000..3db058a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+import 'infer_consts_transitively_2.dart';
+import 'infer_consts_transitively_2_b.dart';
+
+const a1 = m2;
+const a2 = b1;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3db058a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+import 'infer_consts_transitively_2.dart';
+import 'infer_consts_transitively_2_b.dart';
+
+const a1 = m2;
+const a2 = b1;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_consts_transitively_2_b.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_consts_transitively_2_b.dart.textual_outline.expect
new file mode 100644
index 0000000..53d59d9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_consts_transitively_2_b.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+const b1 = 2;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_consts_transitively_2_b.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_consts_transitively_2_b.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..53d59d9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_consts_transitively_2_b.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+const b1 = 2;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_consts_transitively_b.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_consts_transitively_b.dart.textual_outline.expect
new file mode 100644
index 0000000..53d59d9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_consts_transitively_b.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+const b1 = 2;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_consts_transitively_b.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_consts_transitively_b.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..53d59d9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_consts_transitively_b.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+const b1 = 2;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.textual_outline.expect
new file mode 100644
index 0000000..8a3d947
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+class A {
+ var x, y = 2, z = "hi";
+}
+
+class B implements A {
+ var x = 2, y = 3, z, w = 2;
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8a3d947
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+class A {
+ var x, y = 2, z = "hi";
+}
+
+class B implements A {
+ var x = 2, y = 3, z, w = 2;
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_field.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_field.dart.textual_outline.expect
new file mode 100644
index 0000000..449b974
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_field.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+class A implements B {
+ var x;
+}
+
+class B {
+ var x = 0;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_field.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_field.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..449b974
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_field.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+class A implements B {
+ var x;
+}
+
+class B {
+ var x = 0;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.textual_outline.expect
new file mode 100644
index 0000000..2a897a8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+class A implements B {
+ var x;
+}
+
+abstract class B implements C {
+ get x;
+}
+
+abstract class C {
+ int get x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..baffda4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+abstract class B implements C {
+ get x;
+}
+
+abstract class C {
+ int get x;
+}
+
+class A implements B {
+ var x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.textual_outline.expect
new file mode 100644
index 0000000..953911e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+class A implements B {
+ var x;
+}
+
+abstract class B implements C {
+ void set x(value);
+}
+
+abstract class C {
+ void set x(int value);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8533862
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+abstract class B implements C {
+ void set x(value);
+}
+
+abstract class C {
+ void set x(int value);
+}
+
+class A implements B {
+ var x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.textual_outline.expect
new file mode 100644
index 0000000..0636207
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.textual_outline.expect
@@ -0,0 +1,35 @@
+library test;
+
+abstract class A {
+ int get x;
+}
+
+abstract class B {
+ int get x;
+}
+
+abstract class C {
+ num get x;
+}
+
+abstract class D {
+ double get x;
+}
+
+class E extends A implements B {
+ var x;
+}
+
+class F extends A implements C {
+ var x;
+}
+
+class G extends A implements D {
+ var x;
+}
+
+class H extends C implements D {
+ var x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0636207
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.textual_outline_modelled.expect
@@ -0,0 +1,35 @@
+library test;
+
+abstract class A {
+ int get x;
+}
+
+abstract class B {
+ int get x;
+}
+
+abstract class C {
+ num get x;
+}
+
+abstract class D {
+ double get x;
+}
+
+class E extends A implements B {
+ var x;
+}
+
+class F extends A implements C {
+ var x;
+}
+
+class G extends A implements D {
+ var x;
+}
+
+class H extends C implements D {
+ var x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.textual_outline.expect
new file mode 100644
index 0000000..57505e0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+abstract class A {
+ num get x;
+}
+
+abstract class B extends A {
+ int get x;
+}
+
+class C extends B {
+ var x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..57505e0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+abstract class A {
+ num get x;
+}
+
+abstract class B extends A {
+ int get x;
+}
+
+class C extends B {
+ var x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.textual_outline.expect
new file mode 100644
index 0000000..1a94541
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+abstract class A<T> {
+ List<T> get x;
+ void set y(List<T> value);
+ List<T> z;
+}
+
+class B extends A<int> {
+ var x;
+ var y;
+ var z;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..793f675
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+abstract class A<T> {
+ List<T> get x;
+ List<T> z;
+ void set y(List<T> value);
+}
+
+class B extends A<int> {
+ var x;
+ var y;
+ var z;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.textual_outline.expect
new file mode 100644
index 0000000..ae8f2ea
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.textual_outline.expect
@@ -0,0 +1,31 @@
+library test;
+
+abstract class A {
+ int get x;
+}
+
+class B {
+ int get x => 0;
+}
+
+class C extends A {
+ var x;
+}
+
+class D extends B {
+ var x;
+}
+
+class E implements A {
+ var x;
+}
+
+class F implements B {
+ var x;
+}
+
+class G extends Object with B {
+ var x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ae8f2ea
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.textual_outline_modelled.expect
@@ -0,0 +1,31 @@
+library test;
+
+abstract class A {
+ int get x;
+}
+
+class B {
+ int get x => 0;
+}
+
+class C extends A {
+ var x;
+}
+
+class D extends B {
+ var x;
+}
+
+class E implements A {
+ var x;
+}
+
+class F implements B {
+ var x;
+}
+
+class G extends Object with B {
+ var x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.textual_outline.expect
new file mode 100644
index 0000000..4758097
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.textual_outline.expect
@@ -0,0 +1,31 @@
+library test;
+
+abstract class A {
+ void set x(int value);
+}
+
+class B {
+ void set x(int value) {}
+}
+
+class C extends A {
+ var x;
+}
+
+class D extends B {
+ var x;
+}
+
+class E implements A {
+ var x;
+}
+
+class F implements B {
+ var x;
+}
+
+class G extends Object with B {
+ var x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4758097
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.textual_outline_modelled.expect
@@ -0,0 +1,31 @@
+library test;
+
+abstract class A {
+ void set x(int value);
+}
+
+class B {
+ void set x(int value) {}
+}
+
+class C extends A {
+ var x;
+}
+
+class D extends B {
+ var x;
+}
+
+class E implements A {
+ var x;
+}
+
+class F implements B {
+ var x;
+}
+
+class G extends Object with B {
+ var x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_field_static.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_field_static.dart.textual_outline.expect
new file mode 100644
index 0000000..7a13d2a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_static.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+library test;
+
+dynamic f() => null;
+
+abstract class A {
+ static int get x => 0;
+}
+
+class B extends A {
+ static var x = f();
+}
+
+class C extends A {
+ static var x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_field_static.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_field_static.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a746ec3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_static.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+library test;
+
+abstract class A {
+ static int get x => 0;
+}
+
+class B extends A {
+ static var x = f();
+}
+
+class C extends A {
+ static var x;
+}
+
+dynamic f() => null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.textual_outline.expect
new file mode 100644
index 0000000..2fcbeb6b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+abstract class A {
+ int get x;
+ void set x(double value) {}
+}
+
+class B extends A {
+ final x;
+ B(this.x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..226c18d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+abstract class A {
+ int get x;
+ void set x(double value) {}
+}
+
+class B extends A {
+ B(this.x);
+ final x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.textual_outline.expect
new file mode 100644
index 0000000..98e63d7
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+abstract class A {
+ int get x;
+}
+
+class B extends A {
+ final x;
+ B(this.x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2c719f5
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+abstract class A {
+ int get x;
+}
+
+class B extends A {
+ B(this.x);
+ final x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.textual_outline.expect
new file mode 100644
index 0000000..e6b33d7
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+abstract class A {
+ void set x(double value) {}
+}
+
+class B extends A {
+ final x;
+ B(this.x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3b763af
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+abstract class A {
+ void set x(double value) {}
+}
+
+class B extends A {
+ B(this.x);
+ final x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.textual_outline.expect
new file mode 100644
index 0000000..1c2997f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.textual_outline.expect
@@ -0,0 +1,24 @@
+library test;
+
+class A {
+ int x;
+ B operator +(other) => null;
+}
+
+class B extends A {
+ B(ignore);
+}
+
+var a = new A();
+var b = new B(x);
+var c1 = [x];
+var c2 = const [];
+var d = <dynamic, dynamic>{'a': 'b'};
+var e = new A()..x = 3;
+var f = 2 + 3;
+var g = -3;
+var h = new A() + 3;
+var i = -new A();
+var j = null as B;
+test1() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4e2fe4c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+library test;
+
+class A {
+ B operator +(other) => null;
+ int x;
+}
+
+class B extends A {
+ B(ignore);
+}
+
+main() {}
+test1() {}
+var a = new A();
+var b = new B(x);
+var c1 = [x];
+var c2 = const [];
+var d = <dynamic, dynamic>{'a': 'b'};
+var e = new A()..x = 3;
+var f = 2 + 3;
+var g = -3;
+var h = new A() + 3;
+var i = -new A();
+var j = null as B;
diff --git a/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields.dart.textual_outline.expect
new file mode 100644
index 0000000..34ce1a3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+class A {
+ var x;
+}
+
+class B implements A {
+ var x = 2;
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..34ce1a3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+class A {
+ var x;
+}
+
+class B implements A {
+ var x = 2;
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields2.dart.textual_outline.expect
new file mode 100644
index 0000000..aa0f066
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields2.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+class A {
+ final x = null;
+}
+
+class B implements A {
+ final x = 2;
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..aa0f066
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields2.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+class A {
+ final x = null;
+}
+
+class B implements A {
+ final x = 2;
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.textual_outline.expect
new file mode 100644
index 0000000..d492a1f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+import 'infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart';
+
+var y = x;
+test1() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7f49eac
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+import 'infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart';
+
+main() {}
+test1() {}
+var y = x;
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.textual_outline.expect
new file mode 100644
index 0000000..88b9f22
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+import 'infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart';
+
+class B {
+ static var y = A.x;
+}
+
+test1() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d1c629e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+import 'infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart';
+
+class B {
+ static var y = A.x;
+}
+
+main() {}
+test1() {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.textual_outline.expect
new file mode 100644
index 0000000..4506b1e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+import 'infer_from_variables_in_cycle_libs_when_flag_is_on2.dart';
+
+class A {
+ static var x = 2;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4506b1e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+import 'infer_from_variables_in_cycle_libs_when_flag_is_on2.dart';
+
+class A {
+ static var x = 2;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.textual_outline.expect
new file mode 100644
index 0000000..b6179eb
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'infer_from_variables_in_cycle_libs_when_flag_is_on2.dart';
+
+var x = 2;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7bbfa38
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'infer_from_variables_in_cycle_libs_when_flag_is_on2.dart';
+
+main() {}
+var x = 2;
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.textual_outline.expect
new file mode 100644
index 0000000..3866c4e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+import 'infer_from_variables_in_non_cycle_imports_with_flag_a.dart';
+
+var y = x;
+test1() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bc53ea1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+import 'infer_from_variables_in_non_cycle_imports_with_flag_a.dart';
+
+main() {}
+test1() {}
+var y = x;
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.textual_outline.expect
new file mode 100644
index 0000000..7aa039a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+import 'infer_from_variables_in_non_cycle_imports_with_flag2_a.dart';
+
+class B {
+ static var y = A.x;
+}
+
+test1() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5077b56
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+import 'infer_from_variables_in_non_cycle_imports_with_flag2_a.dart';
+
+class B {
+ static var y = A.x;
+}
+
+main() {}
+test1() {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2_a.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2_a.dart.textual_outline.expect
new file mode 100644
index 0000000..7525c2b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2_a.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class A {
+ static var x = 2;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2_a.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2_a.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7525c2b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2_a.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+class A {
+ static var x = 2;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag_a.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag_a.dart.textual_outline.expect
new file mode 100644
index 0000000..bd89adb
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag_a.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+var x = 2;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag_a.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag_a.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a415471
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag_a.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+main() {}
+var x = 2;
diff --git a/pkg/front_end/testcases/inference/infer_generic_field_types.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_generic_field_types.dart.textual_outline.expect
new file mode 100644
index 0000000..62a3a59
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_generic_field_types.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+class A<X> {
+ X field;
+}
+
+abstract class B<Y> implements A<Y> {
+ get field;
+ set field(value);
+}
+
+abstract class C implements A<int> {
+ get field;
+ set field(value);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_generic_field_types.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_generic_field_types.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3a0740d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_generic_field_types.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+abstract class B<Y> implements A<Y> {
+ get field;
+ set field(value);
+}
+
+abstract class C implements A<int> {
+ get field;
+ set field(value);
+}
+
+class A<X> {
+ X field;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_generic_method_type_named.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_generic_method_type_named.dart.textual_outline.expect
new file mode 100644
index 0000000..e30c11e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_generic_method_type_named.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+ T m<T>(int a, {String b, T c}) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_generic_method_type_named.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_generic_method_type_named.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e30c11e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_generic_method_type_named.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+ T m<T>(int a, {String b, T c}) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_generic_method_type_positional.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_generic_method_type_positional.dart.textual_outline.expect
new file mode 100644
index 0000000..067bf3d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_generic_method_type_positional.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+ T m<T>(int a, [T b]) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_generic_method_type_positional.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_generic_method_type_positional.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..067bf3d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_generic_method_type_positional.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+ T m<T>(int a, [T b]) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_generic_method_type_positional2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_generic_method_type_positional2.dart.textual_outline.expect
new file mode 100644
index 0000000..bb6abf4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_generic_method_type_positional2.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+ T m<T>(int a, [String b, T c]) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_generic_method_type_positional2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_generic_method_type_positional2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bb6abf4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_generic_method_type_positional2.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+ T m<T>(int a, [String b, T c]) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_generic_method_type_required.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_generic_method_type_required.dart.textual_outline.expect
new file mode 100644
index 0000000..62d0c61
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_generic_method_type_required.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+ T m<T>(T x) => x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_generic_method_type_required.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_generic_method_type_required.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..62d0c61
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_generic_method_type_required.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+ T m<T>(T x) => x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.textual_outline.expect
new file mode 100644
index 0000000..110bf8d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+abstract class A {
+ void set x(double value);
+}
+
+abstract class B extends A {
+ get x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..110bf8d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+abstract class A {
+ void set x(double value);
+}
+
+abstract class B extends A {
+ get x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.textual_outline.expect
new file mode 100644
index 0000000..32a29d8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+library test;
+
+class A implements B {
+ get x => f();
+}
+
+abstract class B implements C {
+ get x;
+}
+
+abstract class C {
+ int get x;
+}
+
+dynamic f() => null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1b7bfe1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+library test;
+
+abstract class B implements C {
+ get x;
+}
+
+abstract class C {
+ int get x;
+}
+
+class A implements B {
+ get x => f();
+}
+
+dynamic f() => null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_list_literal_nested_in_map_literal.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_list_literal_nested_in_map_literal.dart.textual_outline.expect
new file mode 100644
index 0000000..2ba130d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_list_literal_nested_in_map_literal.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+class Resource {}
+
+class Folder extends Resource {}
+
+Resource getResource(String str) => null;
+
+class Foo<T> {
+ Foo(T t);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_list_literal_nested_in_map_literal.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_list_literal_nested_in_map_literal.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a02d3d4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_list_literal_nested_in_map_literal.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+Resource getResource(String str) => null;
+
+class Folder extends Resource {}
+
+class Foo<T> {
+ Foo(T t);
+}
+
+class Resource {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.textual_outline.expect
new file mode 100644
index 0000000..c70c84a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..10819ea
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.textual_outline.expect
new file mode 100644
index 0000000..c70c84a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..10819ea
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/infer_method_function_typed.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_method_function_typed.dart.textual_outline.expect
new file mode 100644
index 0000000..289c1fe
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_method_function_typed.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+typedef int F();
+
+abstract class A {
+ void x(F value);
+}
+
+abstract class B extends A {
+ void x(value());
+}
+
+T f<T>() => null;
+g(B b) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_method_function_typed.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_method_function_typed.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1a02e51
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_method_function_typed.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+T f<T>() => null;
+
+abstract class A {
+ void x(F value);
+}
+
+abstract class B extends A {
+ void x(value());
+}
+
+g(B b) {}
+main() {}
+typedef int F();
diff --git a/pkg/front_end/testcases/inference/infer_method_missing_params.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_method_missing_params.dart.textual_outline.expect
new file mode 100644
index 0000000..ef2bee8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_method_missing_params.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+library test;
+
+abstract class A {
+ int f(int x, int y);
+ int g(int x, [int y]);
+ int h(int x, {int y});
+}
+
+abstract class B {
+ int f(int x);
+ int g(int x);
+ int h(int x);
+}
+
+abstract class C implements A, B {
+ f(x, y);
+ g(x, [y]);
+ h(x, {y});
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_method_missing_params.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_method_missing_params.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ef2bee8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_method_missing_params.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+library test;
+
+abstract class A {
+ int f(int x, int y);
+ int g(int x, [int y]);
+ int h(int x, {int y});
+}
+
+abstract class B {
+ int f(int x);
+ int g(int x);
+ int h(int x);
+}
+
+abstract class C implements A, B {
+ f(x, y);
+ g(x, [y]);
+ h(x, {y});
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_field.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_field.dart.textual_outline.expect
new file mode 100644
index 0000000..865f30c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_field.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C extends D {
+ set foo(x) {}
+}
+
+class D {
+ int foo;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_field.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_field.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..865f30c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_field.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C extends D {
+ set foo(x) {}
+}
+
+class D {
+ int foo;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_setter.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_setter.dart.textual_outline.expect
new file mode 100644
index 0000000..275351d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_setter.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C extends D {
+ set foo(x) {}
+}
+
+class D {
+ set foo(int x) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_setter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_setter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..275351d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_setter.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C extends D {
+ set foo(x) {}
+}
+
+class D {
+ set foo(int x) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_prefix_expression.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_prefix_expression.dart.textual_outline.expect
new file mode 100644
index 0000000..a4602b1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_prefix_expression.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+var a_not = !true;
+var a_complement = ~1;
+var a_negate = -1;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_prefix_expression.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_prefix_expression.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..927498a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_prefix_expression.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+main() {}
+var a_complement = ~1;
+var a_negate = -1;
+var a_not = !true;
diff --git a/pkg/front_end/testcases/inference/infer_prefix_expression_custom.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_prefix_expression_custom.dart.textual_outline.expect
new file mode 100644
index 0000000..c9d8c68
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_prefix_expression_custom.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+class A {
+ A();
+ int operator ~() => 1;
+ double operator -() => 2.0;
+}
+
+var a = new A();
+var v_complement = ~a;
+var v_negate = -a;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_prefix_expression_custom.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_prefix_expression_custom.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1cedf13
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_prefix_expression_custom.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+class A {
+ A();
+ double operator -() => 2.0;
+ int operator ~() => 1;
+}
+
+main() {}
+var a = new A();
+var v_complement = ~a;
+var v_negate = -a;
diff --git a/pkg/front_end/testcases/inference/infer_rethrow.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_rethrow.dart.textual_outline.expect
new file mode 100644
index 0000000..a3b6c53
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_rethrow.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+test(f(), g()) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_rethrow.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_rethrow.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8a9809c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_rethrow.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+test(f(), g()) {}
diff --git a/pkg/front_end/testcases/inference/infer_return_of_statement_lambda.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_return_of_statement_lambda.dart.textual_outline.expect
new file mode 100644
index 0000000..4707e1b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_return_of_statement_lambda.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+List<String> strings() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_return_of_statement_lambda.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_return_of_statement_lambda.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4707e1b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_return_of_statement_lambda.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+List<String> strings() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.textual_outline.expect
new file mode 100644
index 0000000..659aede
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C {
+ static set foo(int x) {}
+}
+
+set bar(int x) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5e7be8e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C {
+ static set foo(int x) {}
+}
+
+main() {}
+set bar(int x) {}
diff --git a/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.textual_outline.expect
new file mode 100644
index 0000000..250fada
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+abstract class A {
+ double get x;
+}
+
+abstract class B extends A {
+ void set x(value);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..250fada
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+abstract class A {
+ double get x;
+}
+
+abstract class B extends A {
+ void set x(value);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.textual_outline.expect
new file mode 100644
index 0000000..9f48a64
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+class A implements B {
+ void set x(value) {}
+}
+
+abstract class B implements C {
+ void set x(value);
+}
+
+abstract class C {
+ void set x(int value);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c70b4f6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+abstract class B implements C {
+ void set x(value);
+}
+
+abstract class C {
+ void set x(int value);
+}
+
+class A implements B {
+ void set x(value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_setter_function_typed.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_setter_function_typed.dart.textual_outline.expect
new file mode 100644
index 0000000..6f14c5a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_setter_function_typed.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+typedef int F();
+
+abstract class A {
+ void set x(F value);
+}
+
+abstract class B extends A {
+ void set x(value());
+}
+
+T f<T>() => null;
+g(B b) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_setter_function_typed.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_setter_function_typed.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..558610c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_setter_function_typed.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+T f<T>() => null;
+
+abstract class A {
+ void set x(F value);
+}
+
+abstract class B extends A {
+ void set x(value());
+}
+
+g(B b) {}
+main() {}
+typedef int F();
diff --git a/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.textual_outline.expect
new file mode 100644
index 0000000..eb6e1ec
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+class A {
+ void set x(int i) {}
+}
+
+class B extends A {
+ set x(Object o) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..eb6e1ec
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+class A {
+ void set x(int i) {}
+}
+
+class B extends A {
+ set x(Object o) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_statics_transitively.dart.textual_outline.expect
new file mode 100644
index 0000000..a2adc8c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+import 'infer_statics_transitively_a.dart';
+
+final m1 = a1;
+final m2 = A.a2;
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_statics_transitively.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a2adc8c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+import 'infer_statics_transitively_a.dart';
+
+final m1 = a1;
+final m2 = A.a2;
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_statics_transitively2.dart.textual_outline.expect
new file mode 100644
index 0000000..3c1f88e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively2.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+const x1 = 1;
+final x2 = 1;
+final y1 = x1;
+final y2 = x2;
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_statics_transitively2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3c1f88e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively2.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+const x1 = 1;
+final x2 = 1;
+final y1 = x1;
+final y2 = x2;
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.textual_outline.expect
new file mode 100644
index 0000000..3ff7fa6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'infer_statics_transitively3_a.dart' show a1, A;
+import 'infer_statics_transitively3_a.dart' as p show a2, A;
+
+const t1 = 1;
+const t2 = t1;
+const t3 = a1;
+const t4 = p.a2;
+const t5 = A.a3;
+const t6 = p.A.a3;
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3ff7fa6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+import 'infer_statics_transitively3_a.dart' show a1, A;
+import 'infer_statics_transitively3_a.dart' as p show a2, A;
+
+const t1 = 1;
+const t2 = t1;
+const t3 = a1;
+const t4 = p.a2;
+const t5 = A.a3;
+const t6 = p.A.a3;
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively3_a.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_statics_transitively3_a.dart.textual_outline.expect
new file mode 100644
index 0000000..ef4e7b4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively3_a.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+const a1 = 3;
+const a2 = 4;
+
+class A {
+ static const a3 = null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively3_a.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_statics_transitively3_a.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..594222f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively3_a.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class A {
+ static const a3 = null;
+}
+
+const a1 = 3;
+const a2 = 4;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.textual_outline.expect
new file mode 100644
index 0000000..905ce2e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+import 'infer_statics_transitively.dart';
+import 'infer_statics_transitively_b.dart';
+
+final a1 = m2;
+
+class A {
+ static final a2 = b1;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e6e4d7e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+import 'infer_statics_transitively.dart';
+import 'infer_statics_transitively_b.dart';
+
+class A {
+ static final a2 = b1;
+}
+
+final a1 = m2;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.textual_outline.expect
new file mode 100644
index 0000000..905ce2e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+import 'infer_statics_transitively.dart';
+import 'infer_statics_transitively_b.dart';
+
+final a1 = m2;
+
+class A {
+ static final a2 = b1;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e6e4d7e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+import 'infer_statics_transitively.dart';
+import 'infer_statics_transitively_b.dart';
+
+class A {
+ static final a2 = b1;
+}
+
+final a1 = m2;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively_b.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_statics_transitively_b.dart.textual_outline.expect
new file mode 100644
index 0000000..01611d6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively_b.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+final b1 = 2;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively_b.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_statics_transitively_b.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..01611d6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively_b.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+final b1 = 2;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.textual_outline.expect
new file mode 100644
index 0000000..d3d25f6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+import 'infer_statics_with_method_invocations_a.dart';
+
+class T {
+ static final T foo = m1(m2(m3('', '')));
+ static T m1(String m) {}
+ static String m2(e) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bdbc3a1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+import 'infer_statics_with_method_invocations_a.dart';
+
+class T {
+ static String m2(e) {}
+ static T m1(String m) {}
+ static final T foo = m1(m2(m3('', '')));
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_with_method_invocations_a.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_statics_with_method_invocations_a.dart.textual_outline.expect
new file mode 100644
index 0000000..9908614
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_with_method_invocations_a.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+m3(String a, String b, [a1, a2]) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_with_method_invocations_a.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_statics_with_method_invocations_a.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9908614
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_with_method_invocations_a.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+m3(String a, String b, [a1, a2]) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_throw.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_throw.dart.textual_outline.expect
new file mode 100644
index 0000000..7a172c4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_throw.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+var t = true;
+var a = (throw 0);
+var b = (throw 0) ? 1 : 2;
+var c = t ? (throw 1) : 2;
+var d = t ? 1 : (throw 2);
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_throw.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_throw.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5b649fd
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_throw.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+main() {}
+var a = (throw 0);
+var b = (throw 0) ? 1 : 2;
+var c = t ? (throw 1) : 2;
+var d = t ? 1 : (throw 2);
+var t = true;
diff --git a/pkg/front_end/testcases/inference/infer_throw_downwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_throw_downwards.dart.textual_outline.expect
new file mode 100644
index 0000000..d2157a6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_throw_downwards.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+T f<T>() => null;
+var x = throw f();
+void g() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_throw_downwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_throw_downwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e2510ef
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_throw_downwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+T f<T>() => null;
+main() {}
+var x = throw f();
+void g() {}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.textual_outline.expect
new file mode 100644
index 0000000..18f8608
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+class A {
+ int x = 2;
+}
+
+class B extends A {
+ get x => 3;
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..18f8608
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+class A {
+ int x = 2;
+}
+
+class B extends A {
+ get x => 3;
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.textual_outline.expect
new file mode 100644
index 0000000..29aa0a4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+class A {
+ final int x = 2;
+}
+
+class B implements A {
+ get x => 3;
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..29aa0a4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+class A {
+ final int x = 2;
+}
+
+class B implements A {
+ get x => 3;
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_var.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_type_on_var.dart.textual_outline.expect
new file mode 100644
index 0000000..a73b3f8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_on_var.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+test1() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_var.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_type_on_var.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..128ffb9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_on_var.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+test1() {}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_var2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_type_on_var2.dart.textual_outline.expect
new file mode 100644
index 0000000..715fb78
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_on_var2.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+test2() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_var2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_type_on_var2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c5447d1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_on_var2.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+test2() {}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart.textual_outline.expect
new file mode 100644
index 0000000..f68289e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class A {
+ int x = 0;
+ test1() {}
+ int y;
+ final z = 42;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2cea60e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class A {
+ final z = 42;
+ int x = 0;
+ int y;
+ test1() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart.textual_outline.expect
new file mode 100644
index 0000000..fdb603c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+int x = 0;
+test1() {}
+int y = 0;
+final z = 42;
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9ad86a2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+final z = 42;
+int x = 0;
+int y = 0;
+main() {}
+test1() {}
diff --git a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.textual_outline.expect
new file mode 100644
index 0000000..38d22e6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+library test;
+
+import 'infer_type_regardless_of_declaration_order_or_cycles_b.dart';
+
+class C extends B {
+ get x => null;
+}
+
+class A {
+ int get x => 0;
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..17812e9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+library test;
+
+import 'infer_type_regardless_of_declaration_order_or_cycles_b.dart';
+
+class A {
+ int get x => 0;
+}
+
+class C extends B {
+ get x => null;
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.textual_outline.expect
new file mode 100644
index 0000000..0c9213c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'infer_type_regardless_of_declaration_order_or_cycles.dart';
+
+class B extends A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0c9213c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import 'infer_type_regardless_of_declaration_order_or_cycles.dart';
+
+class B extends A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_typed_map_literal.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_typed_map_literal.dart.textual_outline.expect
new file mode 100644
index 0000000..36cd503
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_typed_map_literal.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+var a = <int, String>{0: 'aaa', 1: 'bbb'};
+var b = <double, int>{1.1: 1, 2.2: 2};
+var c = <List<int>, Map<String, double>>{};
+var d = <int, dynamic>{};
+var e = <dynamic, int>{};
+var f = <dynamic, dynamic>{};
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_typed_map_literal.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_typed_map_literal.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4531ba6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_typed_map_literal.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+main() {}
+var a = <int, String>{0: 'aaa', 1: 'bbb'};
+var b = <double, int>{1.1: 1, 2.2: 2};
+var c = <List<int>, Map<String, double>>{};
+var d = <int, dynamic>{};
+var e = <dynamic, int>{};
+var f = <dynamic, dynamic>{};
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.textual_outline.expect
new file mode 100644
index 0000000..0024591
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+library test;
+
+class A<T> {
+ final T x = null;
+ final T w = null;
+}
+
+class B implements A<int> {
+ get x => 3;
+ get w => "hello";
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..55397b8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+library test;
+
+class A<T> {
+ final T w = null;
+ final T x = null;
+}
+
+class B implements A<int> {
+ get w => "hello";
+ get x => 3;
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.textual_outline.expect
new file mode 100644
index 0000000..40264e4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+class A<T> {
+ T x;
+}
+
+class B<E> extends A<E> {
+ E y;
+ get x => y;
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..40264e4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+class A<T> {
+ T x;
+}
+
+class B<E> extends A<E> {
+ E y;
+ get x => y;
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.textual_outline.expect
new file mode 100644
index 0000000..2bc7ba9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.textual_outline.expect
@@ -0,0 +1,23 @@
+library test;
+
+abstract class I<E> {
+ String m(a, String f(v, E e));
+}
+
+abstract class A<E> implements I<E> {
+ const A();
+ String m(a, String f(v, E e));
+}
+
+abstract class M {
+ final int y = 0;
+}
+
+class B<E> extends A<E> implements M {
+ const B();
+ int get y => 0;
+ m(a, f(v, E e)) {}
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..336ae88
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.textual_outline_modelled.expect
@@ -0,0 +1,23 @@
+library test;
+
+abstract class A<E> implements I<E> {
+ String m(a, String f(v, E e));
+ const A();
+}
+
+abstract class I<E> {
+ String m(a, String f(v, E e));
+}
+
+abstract class M {
+ final int y = 0;
+}
+
+class B<E> extends A<E> implements M {
+ const B();
+ int get y => 0;
+ m(a, f(v, E e)) {}
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.textual_outline.expect
new file mode 100644
index 0000000..fb866c7
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+library test;
+
+import 'infer_types_on_generic_instantiations_in_library_cycle_a.dart';
+
+abstract class A<E> implements I<E> {
+ const A();
+ final E value = null;
+}
+
+abstract class M {
+ final int y = 0;
+}
+
+class B<E> extends A<E> implements M {
+ const B();
+ int get y => 0;
+ m(a, f(v, int e)) {}
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fb866c7
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+library test;
+
+import 'infer_types_on_generic_instantiations_in_library_cycle_a.dart';
+
+abstract class A<E> implements I<E> {
+ const A();
+ final E value = null;
+}
+
+abstract class M {
+ final int y = 0;
+}
+
+class B<E> extends A<E> implements M {
+ const B();
+ int get y => 0;
+ m(a, f(v, int e)) {}
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.textual_outline.expect
new file mode 100644
index 0000000..05abbc2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+import 'infer_types_on_generic_instantiations_in_library_cycle.dart';
+
+abstract class I<E> {
+ A<E> m(a, String f(v, int e));
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..05abbc2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+import 'infer_types_on_generic_instantiations_in_library_cycle.dart';
+
+abstract class I<E> {
+ A<E> m(a, String f(v, int e));
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_infer.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_infer.dart.textual_outline.expect
new file mode 100644
index 0000000..92c8792
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_infer.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+class A<T> {
+ final T x = null;
+}
+
+class B implements A<int> {
+ dynamic get x => 3;
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_infer.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_infer.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..92c8792
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_infer.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+class A<T> {
+ final T x = null;
+}
+
+class B implements A<int> {
+ dynamic get x => 3;
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart.textual_outline.expect
new file mode 100644
index 0000000..db1a358
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+library test;
+
+class Foo {
+ int bar = 42;
+}
+
+class Bar<T extends Iterable<String>> {
+ void foo(T t) {}
+}
+
+class Baz<T, E extends Iterable<T>, S extends E> {
+ void foo(S t) {}
+}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b1dd9b9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+library test;
+
+class Bar<T extends Iterable<String>> {
+ void foo(T t) {}
+}
+
+class Baz<T, E extends Iterable<T>, S extends E> {
+ void foo(S t) {}
+}
+
+class Foo {
+ int bar = 42;
+}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.textual_outline.expect
new file mode 100644
index 0000000..178b1385
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+library test;
+
+import 'dart:async';
+
+class Foo {
+ int bar = 42;
+}
+
+class Bar<T extends Stream<String>> {
+ foo(T t) async {}
+}
+
+class Baz<T, E extends Stream<T>, S extends E> {
+ foo(S t) async {}
+}
+
+abstract class MyStream<T> extends Stream<T> {
+ factory MyStream() => null;
+}
+
+test() async {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..225ac1c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.textual_outline_modelled.expect
@@ -0,0 +1,22 @@
+library test;
+
+import 'dart:async';
+
+abstract class MyStream<T> extends Stream<T> {
+ factory MyStream() => null;
+}
+
+class Bar<T extends Stream<String>> {
+ foo(T t) async {}
+}
+
+class Baz<T, E extends Stream<T>, S extends E> {
+ foo(S t) async {}
+}
+
+class Foo {
+ int bar = 42;
+}
+
+main() {}
+test() async {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_loop_with_inference.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_loop_with_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..c70c84a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_loop_with_inference.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_loop_with_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_loop_with_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..10819ea
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_loop_with_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/infer_use_of_void_local.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_use_of_void_local.dart.textual_outline.expect
new file mode 100644
index 0000000..37187cb
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_use_of_void_local.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+void f() {}
+void g() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_use_of_void_local.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_use_of_void_local.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4e388e1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_use_of_void_local.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+main() {}
+void f() {}
+void g() {}
diff --git a/pkg/front_end/testcases/inference/infer_variable_void.dart.textual_outline.expect b/pkg/front_end/testcases/inference/infer_variable_void.dart.textual_outline.expect
new file mode 100644
index 0000000..e064860
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_variable_void.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+void f() {}
+var x = f();
+main() {}
diff --git a/pkg/front_end/testcases/inference/infer_variable_void.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/infer_variable_void.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9e93269
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_variable_void.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+main() {}
+var x = f();
+void f() {}
diff --git a/pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart.textual_outline.expect
new file mode 100644
index 0000000..4e7cbdc
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class Foo {
+ var x = 1;
+ Foo([this.x = "1"]);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..57d515d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class Foo {
+ Foo([this.x = "1"]);
+ var x = 1;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_nonstatic_field_depends_on_static_field_complex.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_nonstatic_field_depends_on_static_field_complex.dart.textual_outline.expect
new file mode 100644
index 0000000..ab2bd61
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_nonstatic_field_depends_on_static_field_complex.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C {
+ static var x = 'x';
+ var y = {
+ 'a': {'b': 'c'},
+ 'd': {'e': x}
+ };
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_nonstatic_field_depends_on_static_field_complex.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_nonstatic_field_depends_on_static_field_complex.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ab2bd61
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_nonstatic_field_depends_on_static_field_complex.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C {
+ static var x = 'x';
+ var y = {
+ 'a': {'b': 'c'},
+ 'd': {'e': x}
+ };
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_nonstatic_field_depends_on_top_level_var_simple.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_nonstatic_field_depends_on_top_level_var_simple.dart.textual_outline.expect
new file mode 100644
index 0000000..766e416
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_nonstatic_field_depends_on_top_level_var_simple.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+var x = 'x';
+
+class C {
+ var y = x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_nonstatic_field_depends_on_top_level_var_simple.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_nonstatic_field_depends_on_top_level_var_simple.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fd2cec5
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_nonstatic_field_depends_on_top_level_var_simple.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C {
+ var y = x;
+}
+
+main() {}
+var x = 'x';
diff --git a/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return_void_context.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return_void_context.dart.textual_outline.expect
new file mode 100644
index 0000000..beb68c7
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return_void_context.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+ C(void func()) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return_void_context.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return_void_context.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..beb68c7
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return_void_context.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+ C(void func()) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_cascade.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_cascade.dart.textual_outline.expect
new file mode 100644
index 0000000..3cd51b6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_cascade.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+class A {
+ int a;
+ List<int> b;
+ void m() {}
+}
+
+var v = new A()
+ ..a = 1
+ ..b.add(2)
+ ..m();
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_cascade.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_cascade.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4ef708f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_cascade.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+class A {
+ List<int> b;
+ int a;
+ void m() {}
+}
+
+main() {}
+var v = new A()
+ ..a = 1
+ ..b.add(2)
+ ..m();
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_binary_op.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_custom_binary_op.dart.textual_outline.expect
new file mode 100644
index 0000000..e6999dd
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_binary_op.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+class C {
+ bool operator *(C other) => true;
+}
+
+C c = new C();
+var x = c * c;
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_binary_op.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_custom_binary_op.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..82580a5
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_binary_op.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+C c = new C();
+
+class C {
+ bool operator *(C other) => true;
+}
+
+main() {}
+var x = c * c;
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_binary_op_via_interface.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_custom_binary_op_via_interface.dart.textual_outline.expect
new file mode 100644
index 0000000..3c0524e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_binary_op_via_interface.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+class I {
+ bool operator *(C other) => true;
+}
+
+abstract class C implements I {}
+
+C c;
+var x = c * c;
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_binary_op_via_interface.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_custom_binary_op_via_interface.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0ce465b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_binary_op_via_interface.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+C c;
+
+abstract class C implements I {}
+
+class I {
+ bool operator *(C other) => true;
+}
+
+main() {}
+var x = c * c;
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_index_op.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_custom_index_op.dart.textual_outline.expect
new file mode 100644
index 0000000..2d475c3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_index_op.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+ bool operator [](int index) => true;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_index_op.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_custom_index_op.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2d475c3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_index_op.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+ bool operator [](int index) => true;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_index_op_via_interface.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_custom_index_op_via_interface.dart.textual_outline.expect
new file mode 100644
index 0000000..c0719da
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_index_op_via_interface.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class I {
+ bool operator [](int index) => true;
+}
+
+abstract class C implements I {}
+
+f() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_index_op_via_interface.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_custom_index_op_via_interface.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e3d9042
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_index_op_via_interface.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+abstract class C implements I {}
+
+class I {
+ bool operator [](int index) => true;
+}
+
+f() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_unary_op.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_custom_unary_op.dart.textual_outline.expect
new file mode 100644
index 0000000..8f42327
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_unary_op.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+class C {
+ bool operator -() => true;
+}
+
+C c = new C();
+var x = -c;
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_unary_op.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_custom_unary_op.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..faae8e3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_unary_op.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+C c = new C();
+
+class C {
+ bool operator -() => true;
+}
+
+main() {}
+var x = -c;
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_unary_op_via_interface.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_custom_unary_op_via_interface.dart.textual_outline.expect
new file mode 100644
index 0000000..8e685fa
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_unary_op_via_interface.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+class I {
+ bool operator -() => true;
+}
+
+abstract class C implements I {}
+
+C c;
+var x = -c;
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_unary_op_via_interface.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_custom_unary_op_via_interface.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fd59e6e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_unary_op_via_interface.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+C c;
+
+abstract class C implements I {}
+
+class I {
+ bool operator -() => true;
+}
+
+main() {}
+var x = -c;
diff --git a/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off.dart.textual_outline.expect
new file mode 100644
index 0000000..f835fa3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+class C {
+ bool g() => true;
+}
+
+C f() => null;
+var x = f().g;
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ef601f2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+C f() => null;
+
+class C {
+ bool g() => true;
+}
+
+main() {}
+var x = f().g;
diff --git a/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off_via_interface.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off_via_interface.dart.textual_outline.expect
new file mode 100644
index 0000000..b33b523
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off_via_interface.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+class I {
+ bool g() => true;
+}
+
+abstract class C implements I {}
+
+C f() => null;
+var x = f().g;
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off_via_interface.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off_via_interface.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c42584c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off_via_interface.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+C f() => null;
+
+abstract class C implements I {}
+
+class I {
+ bool g() => true;
+}
+
+main() {}
+var x = f().g;
diff --git a/pkg/front_end/testcases/inference/inferred_type_from_top_level_executable_tear_off.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_from_top_level_executable_tear_off.dart.textual_outline.expect
new file mode 100644
index 0000000..cff7f24
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_from_top_level_executable_tear_off.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+var v = print;
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_from_top_level_executable_tear_off.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_from_top_level_executable_tear_off.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b24205c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_from_top_level_executable_tear_off.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+var v = print;
diff --git a/pkg/front_end/testcases/inference/inferred_type_invoke_method.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_invoke_method.dart.textual_outline.expect
new file mode 100644
index 0000000..f1ef9c3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_invoke_method.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+class C {
+ bool g() => true;
+}
+
+C f() => null;
+var x = f().g();
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_invoke_method.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_invoke_method.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0f10023
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_invoke_method.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+C f() => null;
+
+class C {
+ bool g() => true;
+}
+
+main() {}
+var x = f().g();
diff --git a/pkg/front_end/testcases/inference/inferred_type_invoke_method_via_interface.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_invoke_method_via_interface.dart.textual_outline.expect
new file mode 100644
index 0000000..ece4df6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_invoke_method_via_interface.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+class I {
+ bool g() => true;
+}
+
+abstract class C implements I {}
+
+C f() => null;
+var x = f().g();
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_invoke_method_via_interface.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_invoke_method_via_interface.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..46f69cc
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_invoke_method_via_interface.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+C f() => null;
+
+abstract class C implements I {}
+
+class I {
+ bool g() => true;
+}
+
+main() {}
+var x = f().g();
diff --git a/pkg/front_end/testcases/inference/inferred_type_is_enum.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_is_enum.dart.textual_outline.expect
new file mode 100644
index 0000000..0ce53ca
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_is_enum.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+enum E { v1 }
+final x = E.v1;
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_is_enum.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_is_enum.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0ce53ca
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_is_enum.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+enum E { v1 }
+final x = E.v1;
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_is_enum_values.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_is_enum_values.dart.textual_outline.expect
new file mode 100644
index 0000000..c3999a2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_is_enum_values.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+enum E { v1 }
+final x = E.values;
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_is_enum_values.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_is_enum_values.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c3999a2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_is_enum_values.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+enum E { v1 }
+final x = E.values;
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_is_typedef.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_is_typedef.dart.textual_outline.expect
new file mode 100644
index 0000000..ef330db
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_is_typedef.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+typedef void F();
+final x = <String, F>{};
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_is_typedef.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_is_typedef.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..19c52ac
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_is_typedef.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+final x = <String, F>{};
+main() {}
+typedef void F();
diff --git a/pkg/front_end/testcases/inference/inferred_type_is_typedef_parameterized.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_is_typedef_parameterized.dart.textual_outline.expect
new file mode 100644
index 0000000..52d5fdc
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_is_typedef_parameterized.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+typedef T F<T>();
+final x = <String, F<int>>{};
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_is_typedef_parameterized.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_is_typedef_parameterized.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8ede87e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_is_typedef_parameterized.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+final x = <String, F<int>>{};
+main() {}
+typedef T F<T>();
diff --git a/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type.dart.textual_outline.expect
new file mode 100644
index 0000000..5f05b3e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+int f() => null;
+String g() => null;
+var v = [f, g];
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0efdef0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+String g() => null;
+int f() => null;
+main() {}
+var v = [f, g];
diff --git a/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_function_typed_param.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_function_typed_param.dart.textual_outline.expect
new file mode 100644
index 0000000..a01e141
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_function_typed_param.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+int f(int x(String y)) => null;
+String g(int x(String y)) => null;
+var v = [f, g];
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_function_typed_param.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_function_typed_param.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f13be17
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_function_typed_param.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+String g(int x(String y)) => null;
+int f(int x(String y)) => null;
+main() {}
+var v = [f, g];
diff --git a/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_named_param.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_named_param.dart.textual_outline.expect
new file mode 100644
index 0000000..f49560d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_named_param.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+int f({int x}) => null;
+String g({int x}) => null;
+var v = [f, g];
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_named_param.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_named_param.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9b9d908
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_named_param.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+String g({int x}) => null;
+int f({int x}) => null;
+main() {}
+var v = [f, g];
diff --git a/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_positional_param.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_positional_param.dart.textual_outline.expect
new file mode 100644
index 0000000..ff5ab50
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_positional_param.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+int f([int x]) => null;
+String g([int x]) => null;
+var v = [f, g];
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_positional_param.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_positional_param.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..99a139a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_positional_param.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+String g([int x]) => null;
+int f([int x]) => null;
+main() {}
+var v = [f, g];
diff --git a/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_required_param.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_required_param.dart.textual_outline.expect
new file mode 100644
index 0000000..4aa6f7c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_required_param.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+int f(int x) => null;
+String g(int x) => null;
+var v = [f, g];
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_required_param.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_required_param.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8eff357
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_required_param.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+String g(int x) => null;
+int f(int x) => null;
+main() {}
+var v = [f, g];
diff --git a/pkg/front_end/testcases/inference/inferred_type_via_closure_multiple_levels_of_nesting.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_via_closure_multiple_levels_of_nesting.dart.textual_outline.expect
new file mode 100644
index 0000000..a5cc028
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_via_closure_multiple_levels_of_nesting.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+ static final f = (bool b) => (int i) => {i: b};
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_via_closure_multiple_levels_of_nesting.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_via_closure_multiple_levels_of_nesting.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a5cc028
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_via_closure_multiple_levels_of_nesting.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+ static final f = (bool b) => (int i) => {i: b};
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_via_closure_type_depends_on_args.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_via_closure_type_depends_on_args.dart.textual_outline.expect
new file mode 100644
index 0000000..fc48846
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_via_closure_type_depends_on_args.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+ static final f = (bool b) => b;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_via_closure_type_depends_on_args.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_via_closure_type_depends_on_args.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fc48846
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_via_closure_type_depends_on_args.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+ static final f = (bool b) => b;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_via_closure_type_independent_of_args_field.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_via_closure_type_independent_of_args_field.dart.textual_outline.expect
new file mode 100644
index 0000000..015c510
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_via_closure_type_independent_of_args_field.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+ static final f = (bool b) => 1;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_via_closure_type_independent_of_args_field.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_via_closure_type_independent_of_args_field.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..015c510
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_via_closure_type_independent_of_args_field.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+ static final f = (bool b) => 1;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_via_closure_type_independent_of_args_top_level.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inferred_type_via_closure_type_independent_of_args_top_level.dart.textual_outline.expect
new file mode 100644
index 0000000..2cfa51b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_via_closure_type_independent_of_args_top_level.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+final f = (bool b) => 1;
+main() {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_via_closure_type_independent_of_args_top_level.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inferred_type_via_closure_type_independent_of_args_top_level.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2cfa51b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_via_closure_type_independent_of_args_top_level.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+final f = (bool b) => 1;
+main() {}
diff --git a/pkg/front_end/testcases/inference/inheritance_does_not_imply_circularity.dart.textual_outline.expect b/pkg/front_end/testcases/inference/inheritance_does_not_imply_circularity.dart.textual_outline.expect
new file mode 100644
index 0000000..134a70e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inheritance_does_not_imply_circularity.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+library test;
+
+class I1 {
+ final x = y;
+}
+
+abstract class I2 {
+ num get x;
+}
+
+class C extends Object implements I1, I2 {
+ int get x => 0;
+}
+
+var y = new C().x;
+main() {}
diff --git a/pkg/front_end/testcases/inference/inheritance_does_not_imply_circularity.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/inheritance_does_not_imply_circularity.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..71382d7
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inheritance_does_not_imply_circularity.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+library test;
+
+abstract class I2 {
+ num get x;
+}
+
+class C extends Object implements I1, I2 {
+ int get x => 0;
+}
+
+class I1 {
+ final x = y;
+}
+
+main() {}
+var y = new C().x;
diff --git a/pkg/front_end/testcases/inference/instance_creation_downwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference/instance_creation_downwards.dart.textual_outline.expect
new file mode 100644
index 0000000..3809765
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instance_creation_downwards.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+class A<T> {
+ A(B<List<T>> b);
+}
+
+class B<T> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/instance_creation_downwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/instance_creation_downwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3809765
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instance_creation_downwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+class A<T> {
+ A(B<List<T>> b);
+}
+
+class B<T> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/instantiate_tearoff.dart.textual_outline.expect b/pkg/front_end/testcases/inference/instantiate_tearoff.dart.textual_outline.expect
new file mode 100644
index 0000000..bfdc465
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_tearoff.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+T f<T>(T x) => x;
+
+class C {
+ T f<T>(T x) => x;
+ static T g<T>(T x) => x;
+}
+
+class D extends C {
+ void test() {}
+}
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/instantiate_tearoff.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/instantiate_tearoff.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..885153c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_tearoff.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+T f<T>(T x) => x;
+
+class C {
+ T f<T>(T x) => x;
+ static T g<T>(T x) => x;
+}
+
+class D extends C {
+ void test() {}
+}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/instantiate_tearoff_after_contravariance_check.dart.textual_outline.expect b/pkg/front_end/testcases/inference/instantiate_tearoff_after_contravariance_check.dart.textual_outline.expect
new file mode 100644
index 0000000..585e21c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_tearoff_after_contravariance_check.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C<T> {
+ void Function(T) f<U>(U x) => (y) {};
+}
+
+void test(C<String> c) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/instantiate_tearoff_after_contravariance_check.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/instantiate_tearoff_after_contravariance_check.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d1a470c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_tearoff_after_contravariance_check.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C<T> {
+ void Function(T) f<U>(U x) => (y) {};
+}
+
+main() {}
+void test(C<String> c) {}
diff --git a/pkg/front_end/testcases/inference/instantiate_tearoff_of_call.dart.textual_outline.expect b/pkg/front_end/testcases/inference/instantiate_tearoff_of_call.dart.textual_outline.expect
new file mode 100644
index 0000000..3ac64a9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_tearoff_of_call.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+void test(T Function<T>(T) f) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/instantiate_tearoff_of_call.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/instantiate_tearoff_of_call.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b579dab
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_tearoff_of_call.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+void test(T Function<T>(T) f) {}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_has_bound_defined_after.dart.textual_outline.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_has_bound_defined_after.dart.textual_outline.expect
new file mode 100644
index 0000000..0e78705
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_has_bound_defined_after.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class B<T extends A> {}
+
+class A<T extends int> {}
+
+B v = null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_has_bound_defined_after.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_has_bound_defined_after.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..25872ad
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_has_bound_defined_after.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+B v = null;
+
+class A<T extends int> {}
+
+class B<T extends A> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_has_bound_defined_before.dart.textual_outline.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_has_bound_defined_before.dart.textual_outline.expect
new file mode 100644
index 0000000..a0a4e79
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_has_bound_defined_before.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class A<T extends int> {}
+
+class B<T extends A> {}
+
+B v = null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_has_bound_defined_before.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_has_bound_defined_before.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..25872ad
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_has_bound_defined_before.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+B v = null;
+
+class A<T extends int> {}
+
+class B<T extends A> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_no_bound.dart.textual_outline.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_no_bound.dart.textual_outline.expect
new file mode 100644
index 0000000..f36f71c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_no_bound.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class A<T> {}
+
+class B<T extends A> {}
+
+B v = null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_no_bound.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_no_bound.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5c6a17a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_no_bound.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+B v = null;
+
+class A<T> {}
+
+class B<T extends A> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_generic_has_bound_defined_after.dart.textual_outline.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic_has_bound_defined_after.dart.textual_outline.expect
new file mode 100644
index 0000000..e88b99a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic_has_bound_defined_after.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+A v = null;
+
+class A<T extends int> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_generic_has_bound_defined_after.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic_has_bound_defined_after.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e88b99a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic_has_bound_defined_after.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+A v = null;
+
+class A<T extends int> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_generic_has_bound_defined_before.dart.textual_outline.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic_has_bound_defined_before.dart.textual_outline.expect
new file mode 100644
index 0000000..e39f07f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic_has_bound_defined_before.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+class A<T extends int> {}
+
+A v = null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_generic_has_bound_defined_before.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic_has_bound_defined_before.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e88b99a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic_has_bound_defined_before.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+A v = null;
+
+class A<T extends int> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_invoke_constructor_no_bound.dart.textual_outline.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_invoke_constructor_no_bound.dart.textual_outline.expect
new file mode 100644
index 0000000..3c2908d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_invoke_constructor_no_bound.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+class C<T> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_invoke_constructor_no_bound.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_invoke_constructor_no_bound.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3c2908d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_invoke_constructor_no_bound.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+class C<T> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_invoke_constructor_type_args_exact.dart.textual_outline.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_invoke_constructor_type_args_exact.dart.textual_outline.expect
new file mode 100644
index 0000000..c265515
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_invoke_constructor_type_args_exact.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+class C<T extends num> {}
+
+var x = new C<int>();
+main() {}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_invoke_constructor_type_args_exact.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_invoke_constructor_type_args_exact.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..71e70ed
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_invoke_constructor_type_args_exact.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+class C<T extends num> {}
+
+main() {}
+var x = new C<int>();
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_not_generic.dart.textual_outline.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_not_generic.dart.textual_outline.expect
new file mode 100644
index 0000000..58d69fb
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_not_generic.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class A {}
+
+class B<T extends A> {}
+
+B v = null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_not_generic.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_not_generic.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e3845e2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_not_generic.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+B v = null;
+
+class A {}
+
+class B<T extends A> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/int_upwards_local.dart.textual_outline.expect b/pkg/front_end/testcases/inference/int_upwards_local.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/int_upwards_local.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/int_upwards_local.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/int_upwards_local.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/int_upwards_local.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/issue41199.dart.textual_outline.expect b/pkg/front_end/testcases/inference/issue41199.dart.textual_outline.expect
new file mode 100644
index 0000000..a90b5ce
--- /dev/null
+++ b/pkg/front_end/testcases/inference/issue41199.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+foo<X>(Map<X, Y> Function<Y>() f) => null;
+baz() => foo(<Z>() => <dynamic, Z>{});
+main() {}
diff --git a/pkg/front_end/testcases/inference/issue41199.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/issue41199.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..81ec7c1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/issue41199.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+baz() => foo(<Z>() => <dynamic, Z>{});
+foo<X>(Map<X, Y> Function<Y>() f) => null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/lambda_does_not_have_propagated_type_hint.dart.textual_outline.expect b/pkg/front_end/testcases/inference/lambda_does_not_have_propagated_type_hint.dart.textual_outline.expect
new file mode 100644
index 0000000..8090ea1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/lambda_does_not_have_propagated_type_hint.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+List<String> getListOfString() => const <String>[];
+void foo() {}
+void bar() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/lambda_does_not_have_propagated_type_hint.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/lambda_does_not_have_propagated_type_hint.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cd53744
--- /dev/null
+++ b/pkg/front_end/testcases/inference/lambda_does_not_have_propagated_type_hint.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+List<String> getListOfString() => const <String>[];
+main() {}
+void bar() {}
+void foo() {}
diff --git a/pkg/front_end/testcases/inference/lambda_return_type.dart.textual_outline.expect b/pkg/front_end/testcases/inference/lambda_return_type.dart.textual_outline.expect
new file mode 100644
index 0000000..431191c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/lambda_return_type.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+typedef num FunctionReturningNum();
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/lambda_return_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/lambda_return_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a159045
--- /dev/null
+++ b/pkg/front_end/testcases/inference/lambda_return_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+main() {}
+test() {}
+typedef num FunctionReturningNum();
diff --git a/pkg/front_end/testcases/inference/lambda_void_context.dart.textual_outline.expect b/pkg/front_end/testcases/inference/lambda_void_context.dart.textual_outline.expect
new file mode 100644
index 0000000..f59c3c4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/lambda_void_context.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+f() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/lambda_void_context.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/lambda_void_context.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f59c3c4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/lambda_void_context.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+f() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/list_literal_typed.dart.textual_outline.expect b/pkg/front_end/testcases/inference/list_literal_typed.dart.textual_outline.expect
new file mode 100644
index 0000000..a8bb8ca
--- /dev/null
+++ b/pkg/front_end/testcases/inference/list_literal_typed.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+var a = <int>[];
+var b = <double>[1.0, 2.0, 3.0];
+var c = <List<int>>[];
+var d = <dynamic>[1, 2.0, false];
+main() {}
diff --git a/pkg/front_end/testcases/inference/list_literal_typed.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/list_literal_typed.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..64454d9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/list_literal_typed.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+main() {}
+var a = <int>[];
+var b = <double>[1.0, 2.0, 3.0];
+var c = <List<int>>[];
+var d = <dynamic>[1, 2.0, false];
diff --git a/pkg/front_end/testcases/inference/list_literals.dart.textual_outline.expect b/pkg/front_end/testcases/inference/list_literals.dart.textual_outline.expect
new file mode 100644
index 0000000..5609202
--- /dev/null
+++ b/pkg/front_end/testcases/inference/list_literals.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+test1() {}
+test2() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/list_literals.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/list_literals.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..140f235
--- /dev/null
+++ b/pkg/front_end/testcases/inference/list_literals.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+main() {}
+test1() {}
+test2() {}
diff --git a/pkg/front_end/testcases/inference/list_literals_can_infer_null_bottom.dart.textual_outline.expect b/pkg/front_end/testcases/inference/list_literals_can_infer_null_bottom.dart.textual_outline.expect
new file mode 100644
index 0000000..a73b3f8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/list_literals_can_infer_null_bottom.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+test1() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/list_literals_can_infer_null_bottom.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/list_literals_can_infer_null_bottom.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..128ffb9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/list_literals_can_infer_null_bottom.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+test1() {}
diff --git a/pkg/front_end/testcases/inference/list_literals_top_level.dart.textual_outline.expect b/pkg/front_end/testcases/inference/list_literals_top_level.dart.textual_outline.expect
new file mode 100644
index 0000000..6756ba5
--- /dev/null
+++ b/pkg/front_end/testcases/inference/list_literals_top_level.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+var x1 = [1, 2, 3];
+test1() {}
+var x2 = [1, 2.0, 3];
+test2() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/list_literals_top_level.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/list_literals_top_level.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f0f5ec2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/list_literals_top_level.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+main() {}
+test1() {}
+test2() {}
+var x1 = [1, 2, 3];
+var x2 = [1, 2.0, 3];
diff --git a/pkg/front_end/testcases/inference/local_constructor_from_arguments.dart.textual_outline.expect b/pkg/front_end/testcases/inference/local_constructor_from_arguments.dart.textual_outline.expect
new file mode 100644
index 0000000..37920c4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/local_constructor_from_arguments.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C<T> {
+ T t;
+ C(this.t);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/local_constructor_from_arguments.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/local_constructor_from_arguments.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c831b3d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/local_constructor_from_arguments.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C<T> {
+ C(this.t);
+ T t;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/local_reference_upwards_local.dart.textual_outline.expect b/pkg/front_end/testcases/inference/local_reference_upwards_local.dart.textual_outline.expect
new file mode 100644
index 0000000..c807ee6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/local_reference_upwards_local.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+import 'dart:async';
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/local_reference_upwards_local.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/local_reference_upwards_local.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c807ee6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/local_reference_upwards_local.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+import 'dart:async';
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/local_return_and_yield.dart.strong.expect b/pkg/front_end/testcases/inference/local_return_and_yield.dart.strong.expect
index 1a8ef87..62c551c 100644
--- a/pkg/front_end/testcases/inference/local_return_and_yield.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/local_return_and_yield.dart.strong.expect
@@ -2,7 +2,8 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/local_return_and_yield.dart:19:38: Error: A value of type 'dynamic Function(dynamic)' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
+// pkg/front_end/testcases/inference/local_return_and_yield.dart:19:38: Error: A value of type 'Future<dynamic Function(dynamic)>' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
+// - 'Future' is from 'dart:async'.
// - 'FutureOr' is from 'dart:async'.
// return /*@ returnType=dynamic */ (/*@ type=dynamic */ x) => x;
// ^
@@ -19,7 +20,8 @@
return (core::int* x) → core::int* => x;
}
function b() → asy::Future<(core::int*) →* core::int*>* async {
- return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/local_return_and_yield.dart:19:38: Error: A value of type 'dynamic Function(dynamic)' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
+ return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/local_return_and_yield.dart:19:38: Error: A value of type 'Future<dynamic Function(dynamic)>' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
+ - 'Future' is from 'dart:async'.
- 'FutureOr' is from 'dart:async'.
return /*@ returnType=dynamic */ (/*@ type=dynamic */ x) => x;
^" in ((dynamic x) → dynamic => x) as{TypeError} asy::FutureOr<(core::int*) →* core::int*>*;
diff --git a/pkg/front_end/testcases/inference/local_return_and_yield.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/local_return_and_yield.dart.strong.transformed.expect
index b2ac7ae..7d91b21 100644
--- a/pkg/front_end/testcases/inference/local_return_and_yield.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/local_return_and_yield.dart.strong.transformed.expect
@@ -2,7 +2,8 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/local_return_and_yield.dart:19:38: Error: A value of type 'dynamic Function(dynamic)' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
+// pkg/front_end/testcases/inference/local_return_and_yield.dart:19:38: Error: A value of type 'Future<dynamic Function(dynamic)>' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
+// - 'Future' is from 'dart:async'.
// - 'FutureOr' is from 'dart:async'.
// return /*@ returnType=dynamic */ (/*@ type=dynamic */ x) => x;
// ^
@@ -30,7 +31,8 @@
try {
#L1:
{
- :return_value = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/local_return_and_yield.dart:19:38: Error: A value of type 'dynamic Function(dynamic)' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
+ :return_value = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/local_return_and_yield.dart:19:38: Error: A value of type 'Future<dynamic Function(dynamic)>' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
+ - 'Future' is from 'dart:async'.
- 'FutureOr' is from 'dart:async'.
return /*@ returnType=dynamic */ (/*@ type=dynamic */ x) => x;
^" in ((dynamic x) → dynamic => x) as{TypeError} asy::FutureOr<(core::int*) →* core::int*>*;
diff --git a/pkg/front_end/testcases/inference/local_return_and_yield.dart.textual_outline.expect b/pkg/front_end/testcases/inference/local_return_and_yield.dart.textual_outline.expect
new file mode 100644
index 0000000..7a5100f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/local_return_and_yield.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+import 'dart:async';
+
+typedef int IntToInt(int i);
+main() {}
diff --git a/pkg/front_end/testcases/inference/local_return_and_yield.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/local_return_and_yield.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ad856ae
--- /dev/null
+++ b/pkg/front_end/testcases/inference/local_return_and_yield.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+import 'dart:async';
+
+main() {}
+typedef int IntToInt(int i);
diff --git a/pkg/front_end/testcases/inference/logical_or_promotion.dart.textual_outline.expect b/pkg/front_end/testcases/inference/logical_or_promotion.dart.textual_outline.expect
new file mode 100644
index 0000000..0562d88
--- /dev/null
+++ b/pkg/front_end/testcases/inference/logical_or_promotion.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+abstract class A {}
+
+abstract class B {}
+
+class C {
+ A a;
+ void f(Object o) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/logical_or_promotion.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/logical_or_promotion.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0562d88
--- /dev/null
+++ b/pkg/front_end/testcases/inference/logical_or_promotion.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+abstract class A {}
+
+abstract class B {}
+
+class C {
+ A a;
+ void f(Object o) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/map_literals.dart.textual_outline.expect b/pkg/front_end/testcases/inference/map_literals.dart.textual_outline.expect
new file mode 100644
index 0000000..5609202
--- /dev/null
+++ b/pkg/front_end/testcases/inference/map_literals.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+test1() {}
+test2() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/map_literals.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/map_literals.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..140f235
--- /dev/null
+++ b/pkg/front_end/testcases/inference/map_literals.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+main() {}
+test1() {}
+test2() {}
diff --git a/pkg/front_end/testcases/inference/map_literals_can_infer_null.dart.textual_outline.expect b/pkg/front_end/testcases/inference/map_literals_can_infer_null.dart.textual_outline.expect
new file mode 100644
index 0000000..a73b3f8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/map_literals_can_infer_null.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+test1() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/map_literals_can_infer_null.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/map_literals_can_infer_null.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..128ffb9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/map_literals_can_infer_null.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+test1() {}
diff --git a/pkg/front_end/testcases/inference/map_literals_top_level.dart.textual_outline.expect b/pkg/front_end/testcases/inference/map_literals_top_level.dart.textual_outline.expect
new file mode 100644
index 0000000..6f3b811
--- /dev/null
+++ b/pkg/front_end/testcases/inference/map_literals_top_level.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+var x1 = {1: 'x', 2: 'y'};
+test1() {}
+var x2 = {1: 'x', 2: 'y', 3.0: new RegExp('.')};
+test2() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/map_literals_top_level.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/map_literals_top_level.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1bd3bfa
--- /dev/null
+++ b/pkg/front_end/testcases/inference/map_literals_top_level.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+main() {}
+test1() {}
+test2() {}
+var x1 = {1: 'x', 2: 'y'};
+var x2 = {1: 'x', 2: 'y', 3.0: new RegExp('.')};
diff --git a/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method.dart.textual_outline.expect b/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method.dart.textual_outline.expect
new file mode 100644
index 0000000..6de6cbe
--- /dev/null
+++ b/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C {
+ D<T> f<T>() => null;
+}
+
+class D<T> {}
+
+var f = new C().f<int>();
+main() {}
diff --git a/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8d922a3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C {
+ D<T> f<T>() => null;
+}
+
+class D<T> {}
+
+main() {}
+var f = new C().f<int>();
diff --git a/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method_identifier_sequence.dart.textual_outline.expect b/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method_identifier_sequence.dart.textual_outline.expect
new file mode 100644
index 0000000..c522b9e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method_identifier_sequence.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C {
+ D<T> f<T>() => null;
+}
+
+class D<T> {}
+
+C c;
+var f = c.f<int>();
+main() {}
diff --git a/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method_identifier_sequence.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method_identifier_sequence.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..18dc8f0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method_identifier_sequence.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+C c;
+
+class C {
+ D<T> f<T>() => null;
+}
+
+class D<T> {}
+
+main() {}
+var f = c.f<int>();
diff --git a/pkg/front_end/testcases/inference/method_call_with_type_arguments_static_method.dart.textual_outline.expect b/pkg/front_end/testcases/inference/method_call_with_type_arguments_static_method.dart.textual_outline.expect
new file mode 100644
index 0000000..add0023
--- /dev/null
+++ b/pkg/front_end/testcases/inference/method_call_with_type_arguments_static_method.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C {
+ static D<T> f<T>() => null;
+}
+
+class D<T> {}
+
+var f = C.f<int>();
+main() {}
diff --git a/pkg/front_end/testcases/inference/method_call_with_type_arguments_static_method.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/method_call_with_type_arguments_static_method.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2f8f547
--- /dev/null
+++ b/pkg/front_end/testcases/inference/method_call_with_type_arguments_static_method.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C {
+ static D<T> f<T>() => null;
+}
+
+class D<T> {}
+
+main() {}
+var f = C.f<int>();
diff --git a/pkg/front_end/testcases/inference/method_call_with_type_arguments_top_level_function.dart.textual_outline.expect b/pkg/front_end/testcases/inference/method_call_with_type_arguments_top_level_function.dart.textual_outline.expect
new file mode 100644
index 0000000..0e5b2a1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/method_call_with_type_arguments_top_level_function.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+D<T> f<T>() => null;
+
+class D<T> {}
+
+var g = f<int>();
+main() {}
diff --git a/pkg/front_end/testcases/inference/method_call_with_type_arguments_top_level_function.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/method_call_with_type_arguments_top_level_function.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6666457
--- /dev/null
+++ b/pkg/front_end/testcases/inference/method_call_with_type_arguments_top_level_function.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+D<T> f<T>() => null;
+
+class D<T> {}
+
+main() {}
+var g = f<int>();
diff --git a/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart.textual_outline.expect b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart.textual_outline.expect
new file mode 100644
index 0000000..0f627e9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class I<X> {}
+
+class M0<X, Y extends String> extends I<X> {}
+
+class M1 implements I<int> {}
+
+class A extends M1 with M0 {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..74e76cf
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class A extends M1 with M0 {}
+
+class I<X> {}
+
+class M0<X, Y extends String> extends I<X> {}
+
+class M1 implements I<int> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart.textual_outline.expect
new file mode 100644
index 0000000..45d38b0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class I<X> {}
+
+class M0<X, Y extends X> extends I<X> {}
+
+class M1 implements I<int> {}
+
+class A extends M1 with M0 {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4c4a6eb
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class A extends M1 with M0 {}
+
+class I<X> {}
+
+class M0<X, Y extends X> extends I<X> {}
+
+class M1 implements I<int> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart.textual_outline.expect b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart.textual_outline.expect
new file mode 100644
index 0000000..4937c62
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class I<X> {}
+
+class M0<X, Y extends Comparable<Y>> extends I<X> {}
+
+class M1 implements I<int> {}
+
+class A extends M1 with M0 {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3a6cbd7
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class A extends M1 with M0 {}
+
+class I<X> {}
+
+class M0<X, Y extends Comparable<Y>> extends I<X> {}
+
+class M1 implements I<int> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart.textual_outline.expect b/pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart.textual_outline.expect
new file mode 100644
index 0000000..0a537f2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+class I<X> {}
+
+class J<X> {}
+
+class M0<X, Y> extends I<X> with J<Y> {}
+
+class M1 implements I<int> {}
+
+class M2 extends M1 implements J<double> {}
+
+class A extends M2 with M0 {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..368c442
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+class A extends M2 with M0 {}
+
+class I<X> {}
+
+class J<X> {}
+
+class M0<X, Y> extends I<X> with J<Y> {}
+
+class M1 implements I<int> {}
+
+class M2 extends M1 implements J<double> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart.textual_outline.expect b/pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart.textual_outline.expect
new file mode 100644
index 0000000..dd6e38e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class I<X> {}
+
+class M0<T> extends I<List<T>> {}
+
+class M1<T> extends I<List<T>> {}
+
+class M2<T> extends M1<Map<T, T>> {}
+
+class A extends M2<int> with M0 {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5ca8e99
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+class A extends M2<int> with M0 {}
+
+class I<X> {}
+
+class M0<T> extends I<List<T>> {}
+
+class M1<T> extends I<List<T>> {}
+
+class M2<T> extends M1<Map<T, T>> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart.textual_outline.expect b/pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart.textual_outline.expect
new file mode 100644
index 0000000..88e4fe0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class I<X> {}
+
+class M0<T> extends I<T> {}
+
+class M1<T> extends I<T> {}
+
+class A extends M0<int> with M1 {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..daa14db
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class A extends M0<int> with M1 {}
+
+class I<X> {}
+
+class M0<T> extends I<T> {}
+
+class M1<T> extends I<T> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart.textual_outline.expect
new file mode 100644
index 0000000..95cdfee
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class I<X> {}
+
+class M0<T> extends I<T> {}
+
+class M1<T> extends I<T> {}
+
+class M2<T> extends I<T> {}
+
+class A extends M0<int> with M1, M2 {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..00c6217
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+class A extends M0<int> with M1, M2 {}
+
+class I<X> {}
+
+class M0<T> extends I<T> {}
+
+class M1<T> extends I<T> {}
+
+class M2<T> extends I<T> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart.textual_outline.expect b/pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart.textual_outline.expect
new file mode 100644
index 0000000..2ef4f06
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class I<X> {}
+
+class M0<T> extends Object implements I<T> {}
+
+class M1<T> extends I<T> {}
+
+class A extends Object with M0, M1<int> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..39209e0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class A extends Object with M0, M1<int> {}
+
+class I<X> {}
+
+class M0<T> extends Object implements I<T> {}
+
+class M1<T> extends I<T> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart.textual_outline.expect b/pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart.textual_outline.expect
new file mode 100644
index 0000000..9eec41a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class I<X> {}
+
+class M0<T> extends Object implements I<T> {}
+
+class M1<T> extends I<T> {}
+
+class A extends Object with M0, M1 implements I<int> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..50e9d09
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class A extends Object with M0, M1 implements I<int> {}
+
+class I<X> {}
+
+class M0<T> extends Object implements I<T> {}
+
+class M1<T> extends I<T> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_unification_1.dart.textual_outline.expect b/pkg/front_end/testcases/inference/mixin_inference_unification_1.dart.textual_outline.expect
new file mode 100644
index 0000000..18ceb4d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_unification_1.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class I<X, Y> {}
+
+class M0<T> implements I<T, int> {}
+
+class M1<T> implements I<String, T> {}
+
+class A extends Object with M0, M1 {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_unification_1.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/mixin_inference_unification_1.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e3a249c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_unification_1.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class A extends Object with M0, M1 {}
+
+class I<X, Y> {}
+
+class M0<T> implements I<T, int> {}
+
+class M1<T> implements I<String, T> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_unification_2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/mixin_inference_unification_2.dart.textual_outline.expect
new file mode 100644
index 0000000..875a303
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_unification_2.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class I<X, Y> {}
+
+class M0<T> implements I<T, List<T>> {}
+
+class M1<T> implements I<List<T>, T> {}
+
+class A extends Object with M0, M1 {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_unification_2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/mixin_inference_unification_2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e8a5311
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_unification_2.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class A extends Object with M0, M1 {}
+
+class I<X, Y> {}
+
+class M0<T> implements I<T, List<T>> {}
+
+class M1<T> implements I<List<T>, T> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/no_error_when_declared_type_is_num_and_assigned_null.dart.textual_outline.expect b/pkg/front_end/testcases/inference/no_error_when_declared_type_is_num_and_assigned_null.dart.textual_outline.expect
new file mode 100644
index 0000000..a73b3f8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/no_error_when_declared_type_is_num_and_assigned_null.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+test1() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/no_error_when_declared_type_is_num_and_assigned_null.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/no_error_when_declared_type_is_num_and_assigned_null.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..128ffb9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/no_error_when_declared_type_is_num_and_assigned_null.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+test1() {}
diff --git a/pkg/front_end/testcases/inference/non_const_invocation.dart.textual_outline.expect b/pkg/front_end/testcases/inference/non_const_invocation.dart.textual_outline.expect
new file mode 100644
index 0000000..a12a138
--- /dev/null
+++ b/pkg/front_end/testcases/inference/non_const_invocation.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+library test;
+
+typedef V F<U, V>(U u);
+
+class Foo<T> {
+ Bar<T> get v1 => new Bar();
+ Bar<List<T>> get v2 => new Bar();
+ Bar<F<T, T>> get v3 => new Bar();
+ Bar<F<F<T, T>, T>> get v4 => new Bar();
+ List<T> get v5 => [];
+ List<F<T, T>> get v6 => [];
+ Map<T, T> get v7 => {};
+ Map<F<T, T>, T> get v8 => {};
+ Map<T, F<T, T>> get v9 => {};
+}
+
+class Bar<T> {
+ const Bar();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/non_const_invocation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/non_const_invocation.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6fb4bb9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/non_const_invocation.dart.textual_outline_modelled.expect
@@ -0,0 +1,20 @@
+library test;
+
+class Bar<T> {
+ const Bar();
+}
+
+class Foo<T> {
+ Bar<F<F<T, T>, T>> get v4 => new Bar();
+ Bar<F<T, T>> get v3 => new Bar();
+ Bar<List<T>> get v2 => new Bar();
+ Bar<T> get v1 => new Bar();
+ List<F<T, T>> get v6 => [];
+ List<T> get v5 => [];
+ Map<F<T, T>, T> get v8 => {};
+ Map<T, F<T, T>> get v9 => {};
+ Map<T, T> get v7 => {};
+}
+
+main() {}
+typedef V F<U, V>(U u);
diff --git a/pkg/front_end/testcases/inference/non_inferrable_getter_setter.dart.textual_outline.expect b/pkg/front_end/testcases/inference/non_inferrable_getter_setter.dart.textual_outline.expect
new file mode 100644
index 0000000..d565888
--- /dev/null
+++ b/pkg/front_end/testcases/inference/non_inferrable_getter_setter.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C {
+ get x => null;
+ void set x(value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/non_inferrable_getter_setter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/non_inferrable_getter_setter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d565888
--- /dev/null
+++ b/pkg/front_end/testcases/inference/non_inferrable_getter_setter.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C {
+ get x => null;
+ void set x(value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/null_aware_method_invocation.dart.textual_outline.expect b/pkg/front_end/testcases/inference/null_aware_method_invocation.dart.textual_outline.expect
new file mode 100644
index 0000000..bdcdbfe
--- /dev/null
+++ b/pkg/front_end/testcases/inference/null_aware_method_invocation.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C {
+ int f() => null;
+}
+
+g(C c) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/null_aware_method_invocation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/null_aware_method_invocation.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bdcdbfe
--- /dev/null
+++ b/pkg/front_end/testcases/inference/null_aware_method_invocation.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C {
+ int f() => null;
+}
+
+g(C c) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/null_aware_property_get.dart.textual_outline.expect b/pkg/front_end/testcases/inference/null_aware_property_get.dart.textual_outline.expect
new file mode 100644
index 0000000..ce42724
--- /dev/null
+++ b/pkg/front_end/testcases/inference/null_aware_property_get.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C {
+ int x;
+}
+
+void f(C c) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/null_aware_property_get.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/null_aware_property_get.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..99cd276
--- /dev/null
+++ b/pkg/front_end/testcases/inference/null_aware_property_get.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C {
+ int x;
+}
+
+main() {}
+void f(C c) {}
diff --git a/pkg/front_end/testcases/inference/null_coalescing_operator.dart.textual_outline.expect b/pkg/front_end/testcases/inference/null_coalescing_operator.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/null_coalescing_operator.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/null_coalescing_operator.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/null_coalescing_operator.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/null_coalescing_operator.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/null_coalescing_operator_2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/null_coalescing_operator_2.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/null_coalescing_operator_2.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/null_coalescing_operator_2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/null_coalescing_operator_2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/null_coalescing_operator_2.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/null_literal_should_not_infer_as_bottom.dart.textual_outline.expect b/pkg/front_end/testcases/inference/null_literal_should_not_infer_as_bottom.dart.textual_outline.expect
new file mode 100644
index 0000000..4a1f36a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/null_literal_should_not_infer_as_bottom.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+var h = null;
+void foo(int f(Object _)) {}
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/null_literal_should_not_infer_as_bottom.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/null_literal_should_not_infer_as_bottom.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1183aa1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/null_literal_should_not_infer_as_bottom.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+main() {}
+test() {}
+var h = null;
+void foo(int f(Object _)) {}
diff --git a/pkg/front_end/testcases/inference/overloaded_int_operators.dart.textual_outline.expect b/pkg/front_end/testcases/inference/overloaded_int_operators.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/overloaded_int_operators.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/overloaded_int_operators.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/overloaded_int_operators.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/overloaded_int_operators.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/override_equals.dart.textual_outline.expect b/pkg/front_end/testcases/inference/override_equals.dart.textual_outline.expect
new file mode 100644
index 0000000..e9719ec
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_equals.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+class NullEquality {
+ @override
+ Null operator ==(Object other) => null;
+}
+
+class SubNullEquality extends NullEquality {
+ void test() {}
+}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/override_equals.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/override_equals.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b6b202b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_equals.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+class NullEquality {
+ @override
+ Null operator ==(Object other) => null;
+}
+
+class SubNullEquality extends NullEquality {
+ void test() {}
+}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.textual_outline.expect b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..60962ed
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class A<X> {
+ final foo = "bar";
+}
+
+class B<Y> extends A<Y> {
+ final foo;
+ B(this.foo);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..dbeb61d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+class A<X> {
+ final foo = "bar";
+}
+
+class B<Y> extends A<Y> {
+ B(this.foo);
+ final foo;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.textual_outline.expect b/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.textual_outline.expect
new file mode 100644
index 0000000..d69f3e8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+abstract class A<X> {
+ void foo({Iterable<X> x});
+}
+
+class B<Y> implements A<Y> {
+ void foo({x}) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d69f3e8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+abstract class A<X> {
+ void foo({Iterable<X> x});
+}
+
+class B<Y> implements A<Y> {
+ void foo({x}) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/parameter_defaults_downwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference/parameter_defaults_downwards.dart.textual_outline.expect
new file mode 100644
index 0000000..0f15872d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/parameter_defaults_downwards.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+void optional_toplevel([List<int> x = const []]) {}
+void named_toplevel({List<int> x: const []}) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/parameter_defaults_downwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/parameter_defaults_downwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..88548f3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/parameter_defaults_downwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+main() {}
+void named_toplevel({List<int> x: const []}) {}
+void optional_toplevel([List<int> x = const []]) {}
diff --git a/pkg/front_end/testcases/inference/parameter_defaults_upwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference/parameter_defaults_upwards.dart.textual_outline.expect
new file mode 100644
index 0000000..99ee48d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/parameter_defaults_upwards.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C<T> {
+ C.optional(void func([T x])) {}
+ C.named(void func({T x})) {}
+}
+
+void optional_toplevel([x = const [0]]) {}
+void named_toplevel({x: const [0]}) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/parameter_defaults_upwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/parameter_defaults_upwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b07f840
--- /dev/null
+++ b/pkg/front_end/testcases/inference/parameter_defaults_upwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C<T> {
+ C.named(void func({T x})) {}
+ C.optional(void func([T x])) {}
+}
+
+main() {}
+void named_toplevel({x: const [0]}) {}
+void optional_toplevel([x = const [0]]) {}
diff --git a/pkg/front_end/testcases/inference/promote_bounds.dart.textual_outline.expect b/pkg/front_end/testcases/inference/promote_bounds.dart.textual_outline.expect
new file mode 100644
index 0000000..a353121
--- /dev/null
+++ b/pkg/front_end/testcases/inference/promote_bounds.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+abstract class B {
+ void foo();
+}
+
+abstract class C extends B {
+ void bar();
+}
+
+void f<T extends B>(T a) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/promote_bounds.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/promote_bounds.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..08ef9b2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/promote_bounds.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+abstract class B {
+ void foo();
+}
+
+abstract class C extends B {
+ void bar();
+}
+
+main() {}
+void f<T extends B>(T a) {}
diff --git a/pkg/front_end/testcases/inference/promote_from_logical_rhs.dart.textual_outline.expect b/pkg/front_end/testcases/inference/promote_from_logical_rhs.dart.textual_outline.expect
new file mode 100644
index 0000000..31d41a0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/promote_from_logical_rhs.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+void test(Object a, bool b) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/promote_from_logical_rhs.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/promote_from_logical_rhs.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..17f0601
--- /dev/null
+++ b/pkg/front_end/testcases/inference/promote_from_logical_rhs.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+void test(Object a, bool b) {}
diff --git a/pkg/front_end/testcases/inference/promotion_subtype_check.dart.textual_outline.expect b/pkg/front_end/testcases/inference/promotion_subtype_check.dart.textual_outline.expect
new file mode 100644
index 0000000..563c2f1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/promotion_subtype_check.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+void f(Object x) {}
+void g(int x) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/promotion_subtype_check.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/promotion_subtype_check.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8442684
--- /dev/null
+++ b/pkg/front_end/testcases/inference/promotion_subtype_check.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+main() {}
+void f(Object x) {}
+void g(int x) {}
diff --git a/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class.dart.textual_outline.expect b/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class.dart.textual_outline.expect
new file mode 100644
index 0000000..99e1514
--- /dev/null
+++ b/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class A {
+ int x = 2;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..99e1514
--- /dev/null
+++ b/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class A {
+ int x = 2;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class_dynamic_warnings.dart.textual_outline.expect b/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class_dynamic_warnings.dart.textual_outline.expect
new file mode 100644
index 0000000..99e1514
--- /dev/null
+++ b/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class_dynamic_warnings.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class A {
+ int x = 2;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class_dynamic_warnings.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class_dynamic_warnings.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..99e1514
--- /dev/null
+++ b/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class_dynamic_warnings.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class A {
+ int x = 2;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.textual_outline.expect b/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.textual_outline.expect
new file mode 100644
index 0000000..40b29e6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class A {
+ int x = 2;
+}
+
+test5() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6ee5c2f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class A {
+ int x = 2;
+}
+
+main() {}
+test5() {}
diff --git a/pkg/front_end/testcases/inference/propagate_inference_transitively2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/propagate_inference_transitively2.dart.textual_outline.expect
new file mode 100644
index 0000000..774ec6d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/propagate_inference_transitively2.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+library test;
+
+class A {
+ int x = 42;
+}
+
+class B {
+ A a = new A();
+}
+
+class C {
+ B b = new B();
+}
+
+class D {
+ C c = new C();
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/inference/propagate_inference_transitively2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/propagate_inference_transitively2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..774ec6d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/propagate_inference_transitively2.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+library test;
+
+class A {
+ int x = 42;
+}
+
+class B {
+ A a = new A();
+}
+
+class C {
+ B b = new B();
+}
+
+class D {
+ C c = new C();
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/inference/propagate_variable_get.dart.textual_outline.expect b/pkg/front_end/testcases/inference/propagate_variable_get.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/propagate_variable_get.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/propagate_variable_get.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/propagate_variable_get.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/propagate_variable_get.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/property_get_toplevel.dart.textual_outline.expect b/pkg/front_end/testcases/inference/property_get_toplevel.dart.textual_outline.expect
new file mode 100644
index 0000000..46d302a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/property_get_toplevel.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+class C {
+ int field = 0;
+ int get getter => 0;
+ int function() => 0;
+}
+
+C c = new C();
+var function_ref = c.function;
+var function_ref_list = [c.function];
+main() {}
diff --git a/pkg/front_end/testcases/inference/property_get_toplevel.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/property_get_toplevel.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cb636c41
--- /dev/null
+++ b/pkg/front_end/testcases/inference/property_get_toplevel.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+C c = new C();
+
+class C {
+ int field = 0;
+ int function() => 0;
+ int get getter => 0;
+}
+
+main() {}
+var function_ref = c.function;
+var function_ref_list = [c.function];
diff --git a/pkg/front_end/testcases/inference/property_set.dart.textual_outline.expect b/pkg/front_end/testcases/inference/property_set.dart.textual_outline.expect
new file mode 100644
index 0000000..fbf41d4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/property_set.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+class A<T> {
+ List<T> x;
+ void set y(List<T> value) {}
+}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/property_set.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/property_set.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..99f7782
--- /dev/null
+++ b/pkg/front_end/testcases/inference/property_set.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+class A<T> {
+ List<T> x;
+ void set y(List<T> value) {}
+}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/inference/property_set_bad_setter.dart.textual_outline.expect b/pkg/front_end/testcases/inference/property_set_bad_setter.dart.textual_outline.expect
new file mode 100644
index 0000000..6eadbb2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/property_set_bad_setter.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class A {
+ void set x() {}
+}
+
+void f(A a) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/property_set_bad_setter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/property_set_bad_setter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3df6a19
--- /dev/null
+++ b/pkg/front_end/testcases/inference/property_set_bad_setter.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class A {
+ void set x() {}
+}
+
+main() {}
+void f(A a) {}
diff --git a/pkg/front_end/testcases/inference/recursive_generic_function.dart.textual_outline.expect b/pkg/front_end/testcases/inference/recursive_generic_function.dart.textual_outline.expect
new file mode 100644
index 0000000..f07684b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/recursive_generic_function.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+void _mergeSort<T>(
+ T Function(T) list, int compare(T a, T b), T Function(T) target) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/recursive_generic_function.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/recursive_generic_function.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0f5ec10
--- /dev/null
+++ b/pkg/front_end/testcases/inference/recursive_generic_function.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+main() {}
+void _mergeSort<T>(
+ T Function(T) list, int compare(T a, T b), T Function(T) target) {}
diff --git a/pkg/front_end/testcases/inference/reference_to_typedef.dart.textual_outline.expect b/pkg/front_end/testcases/inference/reference_to_typedef.dart.textual_outline.expect
new file mode 100644
index 0000000..1868d7f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/reference_to_typedef.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+typedef void F();
+final x = F;
+main() {}
diff --git a/pkg/front_end/testcases/inference/reference_to_typedef.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/reference_to_typedef.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..808266d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/reference_to_typedef.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+final x = F;
+main() {}
+typedef void F();
diff --git a/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_double.dart.textual_outline.expect b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_double.dart.textual_outline.expect
new file mode 100644
index 0000000..0b91a55
--- /dev/null
+++ b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_double.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C<T extends num> {
+ T a;
+ void op(double b) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_double.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_double.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0b91a55
--- /dev/null
+++ b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_double.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C<T extends num> {
+ T a;
+ void op(double b) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_int.dart.textual_outline.expect b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_int.dart.textual_outline.expect
new file mode 100644
index 0000000..e352327
--- /dev/null
+++ b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_int.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+class C<T extends num> {
+ T a;
+ void op(int b) {}
+ void opEq(int b) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_int.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_int.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e352327
--- /dev/null
+++ b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_int.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+class C<T extends num> {
+ T a;
+ void op(int b) {}
+ void opEq(int b) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_t.dart.textual_outline.expect b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_t.dart.textual_outline.expect
new file mode 100644
index 0000000..34c354c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_t.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+class C<T extends num> {
+ T a;
+ void op(T b) {}
+ void opEq(T b) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_t.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_t.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..34c354c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_t.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+class C<T extends num> {
+ T a;
+ void op(T b) {}
+ void opEq(T b) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/setter_return_type.dart.textual_outline.expect b/pkg/front_end/testcases/inference/setter_return_type.dart.textual_outline.expect
new file mode 100644
index 0000000..f9485e8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/setter_return_type.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+class C {
+ dynamic set x(int value) {}
+}
+
+abstract class I {
+ void set x(int value) {}
+}
+
+class D extends C implements I {
+ set x(value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/setter_return_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/setter_return_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..001950d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/setter_return_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+abstract class I {
+ void set x(int value) {}
+}
+
+class C {
+ dynamic set x(int value) {}
+}
+
+class D extends C implements I {
+ set x(value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/simple_literal_bool.dart.textual_outline.expect b/pkg/front_end/testcases/inference/simple_literal_bool.dart.textual_outline.expect
new file mode 100644
index 0000000..452bced
--- /dev/null
+++ b/pkg/front_end/testcases/inference/simple_literal_bool.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+var a = true;
+main() {}
diff --git a/pkg/front_end/testcases/inference/simple_literal_bool.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/simple_literal_bool.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c7a57ef
--- /dev/null
+++ b/pkg/front_end/testcases/inference/simple_literal_bool.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+var a = true;
diff --git a/pkg/front_end/testcases/inference/simple_literal_double.dart.textual_outline.expect b/pkg/front_end/testcases/inference/simple_literal_double.dart.textual_outline.expect
new file mode 100644
index 0000000..04971e0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/simple_literal_double.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+var a = 1.2;
+main() {}
diff --git a/pkg/front_end/testcases/inference/simple_literal_double.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/simple_literal_double.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cb4b7ad
--- /dev/null
+++ b/pkg/front_end/testcases/inference/simple_literal_double.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+var a = 1.2;
diff --git a/pkg/front_end/testcases/inference/simple_literal_int.dart.textual_outline.expect b/pkg/front_end/testcases/inference/simple_literal_int.dart.textual_outline.expect
new file mode 100644
index 0000000..83e091a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/simple_literal_int.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+var a = 1;
+main() {}
diff --git a/pkg/front_end/testcases/inference/simple_literal_int.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/simple_literal_int.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..60b453a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/simple_literal_int.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+var a = 1;
diff --git a/pkg/front_end/testcases/inference/simple_literal_null.dart.textual_outline.expect b/pkg/front_end/testcases/inference/simple_literal_null.dart.textual_outline.expect
new file mode 100644
index 0000000..5ca6d2a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/simple_literal_null.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+var a = null;
+main() {}
diff --git a/pkg/front_end/testcases/inference/simple_literal_null.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/simple_literal_null.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..931bd7b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/simple_literal_null.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+var a = null;
diff --git a/pkg/front_end/testcases/inference/static_method_tear_off.dart.textual_outline.expect b/pkg/front_end/testcases/inference/static_method_tear_off.dart.textual_outline.expect
new file mode 100644
index 0000000..26d186e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/static_method_tear_off.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+const v = C.f;
+
+class C {
+ static int f(String s) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/static_method_tear_off.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/static_method_tear_off.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bf32f5c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/static_method_tear_off.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C {
+ static int f(String s) => null;
+}
+
+const v = C.f;
+main() {}
diff --git a/pkg/front_end/testcases/inference/string_literal.dart.textual_outline.expect b/pkg/front_end/testcases/inference/string_literal.dart.textual_outline.expect
new file mode 100644
index 0000000..40f25d4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/string_literal.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+var x = 1;
+var a = 'aaa';
+var b = 'b ${x} bb';
+var c = 'c ${x} cc' 'ccc';
+main() {}
diff --git a/pkg/front_end/testcases/inference/string_literal.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/string_literal.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8bb8a7d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/string_literal.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+main() {}
+var a = 'aaa';
+var b = 'b ${x} bb';
+var c = 'c ${x} cc' 'ccc';
+var x = 1;
diff --git a/pkg/front_end/testcases/inference/subexpressions_of_explicitly_typed_fields.dart.textual_outline.expect b/pkg/front_end/testcases/inference/subexpressions_of_explicitly_typed_fields.dart.textual_outline.expect
new file mode 100644
index 0000000..46a9d5d9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/subexpressions_of_explicitly_typed_fields.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C {
+ List<num> x = [0];
+}
+
+List<num> y = [0];
+main() {}
diff --git a/pkg/front_end/testcases/inference/subexpressions_of_explicitly_typed_fields.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/subexpressions_of_explicitly_typed_fields.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fa8bd40
--- /dev/null
+++ b/pkg/front_end/testcases/inference/subexpressions_of_explicitly_typed_fields.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+List<num> y = [0];
+
+class C {
+ List<num> x = [0];
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_index_set.dart.textual_outline.expect b/pkg/front_end/testcases/inference/super_index_set.dart.textual_outline.expect
new file mode 100644
index 0000000..dcae9ea
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_index_set.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+library test;
+
+import 'dart:async';
+
+T f<T>() => null;
+
+class B {
+ void operator []=(int x, String y) {}
+}
+
+class C extends B {
+ void operator []=(Object x, Object y) {}
+ void h() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_index_set.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/super_index_set.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..aeaf352
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_index_set.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+library test;
+
+import 'dart:async';
+
+T f<T>() => null;
+
+class B {
+ void operator []=(int x, String y) {}
+}
+
+class C extends B {
+ void h() {}
+ void operator []=(Object x, Object y) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_index_set_substitution.dart.textual_outline.expect b/pkg/front_end/testcases/inference/super_index_set_substitution.dart.textual_outline.expect
new file mode 100644
index 0000000..aac365a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_index_set_substitution.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+library test;
+
+import 'dart:async';
+
+T f<T>() => null;
+
+class B<T> {
+ void operator []=(Map<int, T> x, List<T> y) {}
+}
+
+class C<U> extends B<Future<U>> {
+ void operator []=(Object x, Object y) {}
+ void h() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_index_set_substitution.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/super_index_set_substitution.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5a33bc2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_index_set_substitution.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+library test;
+
+import 'dart:async';
+
+T f<T>() => null;
+
+class B<T> {
+ void operator []=(Map<int, T> x, List<T> y) {}
+}
+
+class C<U> extends B<Future<U>> {
+ void h() {}
+ void operator []=(Object x, Object y) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/inference/super_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..adf9262
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_initializer.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+T f<T>() => null;
+
+class C extends B {
+ C() : super(f());
+}
+
+class B {
+ B(int x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_initializer.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/super_initializer.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d335a89
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_initializer.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+T f<T>() => null;
+
+class B {
+ B(int x);
+}
+
+class C extends B {
+ C() : super(f());
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_initializer_substitution.dart.textual_outline.expect b/pkg/front_end/testcases/inference/super_initializer_substitution.dart.textual_outline.expect
new file mode 100644
index 0000000..9ebda13
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_initializer_substitution.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+T f<T>() => null;
+
+class B<T> {
+ B(T t);
+}
+
+class C<U> extends B<List<U>> {
+ C() : super(f());
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_initializer_substitution.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/super_initializer_substitution.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9ebda13
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_initializer_substitution.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+T f<T>() => null;
+
+class B<T> {
+ B(T t);
+}
+
+class C<U> extends B<List<U>> {
+ C() : super(f());
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_method_invocation.dart.textual_outline.expect b/pkg/front_end/testcases/inference/super_method_invocation.dart.textual_outline.expect
new file mode 100644
index 0000000..705378f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_method_invocation.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C {
+ int f() => 0;
+}
+
+class D extends C {
+ void g() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_method_invocation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/super_method_invocation.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..705378f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_method_invocation.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C {
+ int f() => 0;
+}
+
+class D extends C {
+ void g() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.textual_outline.expect b/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.textual_outline.expect
new file mode 100644
index 0000000..d1bf59d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.textual_outline.expect
@@ -0,0 +1,20 @@
+library test;
+
+import 'dart:async';
+
+T f<T>() => null;
+
+class D<T> {}
+
+class E<T> extends D<T> {}
+
+class B<T> {
+ D<T> g(E<T> x) => null;
+}
+
+class C<U> extends B<Future<U>> {
+ E<Future<U>> g(Object x) => null;
+ void h() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..276cc12
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.textual_outline_modelled.expect
@@ -0,0 +1,20 @@
+library test;
+
+import 'dart:async';
+
+T f<T>() => null;
+
+class B<T> {
+ D<T> g(E<T> x) => null;
+}
+
+class C<U> extends B<Future<U>> {
+ E<Future<U>> g(Object x) => null;
+ void h() {}
+}
+
+class D<T> {}
+
+class E<T> extends D<T> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_property_get.dart.textual_outline.expect b/pkg/front_end/testcases/inference/super_property_get.dart.textual_outline.expect
new file mode 100644
index 0000000..e878396
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_property_get.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C {
+ var x = 0;
+}
+
+class D extends C {
+ void g() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_property_get.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/super_property_get.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e878396
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_property_get.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C {
+ var x = 0;
+}
+
+class D extends C {
+ void g() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_property_get_invoke_function_typed.dart.textual_outline.expect b/pkg/front_end/testcases/inference/super_property_get_invoke_function_typed.dart.textual_outline.expect
new file mode 100644
index 0000000..7d71a90
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_property_get_invoke_function_typed.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C {
+ var f = () => 0;
+}
+
+class D extends C {
+ void g() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_property_get_invoke_function_typed.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/super_property_get_invoke_function_typed.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7d71a90
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_property_get_invoke_function_typed.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C {
+ var f = () => 0;
+}
+
+class D extends C {
+ void g() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_property_get_invoke_implicit_call.dart.textual_outline.expect b/pkg/front_end/testcases/inference/super_property_get_invoke_implicit_call.dart.textual_outline.expect
new file mode 100644
index 0000000..f9b1f9f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_property_get_invoke_implicit_call.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+class CallableClass {
+ int call() => 0;
+}
+
+class C {
+ var f = new CallableClass();
+}
+
+class D extends C {
+ void g() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_property_get_invoke_implicit_call.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/super_property_get_invoke_implicit_call.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4764b64
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_property_get_invoke_implicit_call.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+class C {
+ var f = new CallableClass();
+}
+
+class CallableClass {
+ int call() => 0;
+}
+
+class D extends C {
+ void g() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_property_get_substitution.dart.textual_outline.expect b/pkg/front_end/testcases/inference/super_property_get_substitution.dart.textual_outline.expect
new file mode 100644
index 0000000..fd7f136
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_property_get_substitution.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+library test;
+
+import 'dart:async';
+
+class D<T> {}
+
+class E<T> extends D<T> {}
+
+class B<T> {
+ D<T> x;
+}
+
+class C<U> extends B<Future<U>> {
+ E<Future<U>> get x => null;
+ void set x(Object x) {}
+ void g() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_property_get_substitution.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/super_property_get_substitution.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1082016
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_property_get_substitution.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+library test;
+
+import 'dart:async';
+
+class B<T> {
+ D<T> x;
+}
+
+class C<U> extends B<Future<U>> {
+ E<Future<U>> get x => null;
+ void g() {}
+ void set x(Object x) {}
+}
+
+class D<T> {}
+
+class E<T> extends D<T> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_property_get_tearoff.dart.textual_outline.expect b/pkg/front_end/testcases/inference/super_property_get_tearoff.dart.textual_outline.expect
new file mode 100644
index 0000000..705378f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_property_get_tearoff.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C {
+ int f() => 0;
+}
+
+class D extends C {
+ void g() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_property_get_tearoff.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/super_property_get_tearoff.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..705378f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_property_get_tearoff.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C {
+ int f() => 0;
+}
+
+class D extends C {
+ void g() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_property_set_substitution.dart.textual_outline.expect b/pkg/front_end/testcases/inference/super_property_set_substitution.dart.textual_outline.expect
new file mode 100644
index 0000000..52e795a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_property_set_substitution.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+library test;
+
+import 'dart:async';
+
+T f<T>() => null;
+
+class D<T> {}
+
+class E<T> extends D<T> {}
+
+class B<T> {
+ D<T> x;
+}
+
+class C<U> extends B<Future<U>> {
+ E<Future<U>> get x => null;
+ void set x(Object x) {}
+ void g() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/super_property_set_substitution.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/super_property_set_substitution.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..45e3806
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_property_set_substitution.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+library test;
+
+import 'dart:async';
+
+T f<T>() => null;
+
+class B<T> {
+ D<T> x;
+}
+
+class C<U> extends B<Future<U>> {
+ E<Future<U>> get x => null;
+ void g() {}
+ void set x(Object x) {}
+}
+
+class D<T> {}
+
+class E<T> extends D<T> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/switch_continue.dart.textual_outline.expect b/pkg/front_end/testcases/inference/switch_continue.dart.textual_outline.expect
new file mode 100644
index 0000000..de6340a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/switch_continue.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+void test(int x, void f()) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/switch_continue.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/switch_continue.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3712403
--- /dev/null
+++ b/pkg/front_end/testcases/inference/switch_continue.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+void test(int x, void f()) {}
diff --git a/pkg/front_end/testcases/inference/symbol_literal.dart.textual_outline.expect b/pkg/front_end/testcases/inference/symbol_literal.dart.textual_outline.expect
new file mode 100644
index 0000000..a6bcf94
--- /dev/null
+++ b/pkg/front_end/testcases/inference/symbol_literal.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/symbol_literal.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/symbol_literal.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..72a3ba0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/symbol_literal.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference/this_reference.dart.textual_outline.expect b/pkg/front_end/testcases/inference/this_reference.dart.textual_outline.expect
new file mode 100644
index 0000000..c213951
--- /dev/null
+++ b/pkg/front_end/testcases/inference/this_reference.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C<T> {
+ void f() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/this_reference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/this_reference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c213951
--- /dev/null
+++ b/pkg/front_end/testcases/inference/this_reference.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C<T> {
+ void f() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.strong.expect b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.strong.expect
index a34ea59..dc1653d 100644
--- a/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.strong.expect
@@ -2,7 +2,8 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/top_level_return_and_yield.dart:18:36: Error: A value of type 'dynamic Function(dynamic)' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
+// pkg/front_end/testcases/inference/top_level_return_and_yield.dart:18:36: Error: A value of type 'Future<dynamic Function(dynamic)>' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
+// - 'Future' is from 'dart:async'.
// - 'FutureOr' is from 'dart:async'.
// return /*@ returnType=dynamic */ (/*@ type=dynamic */ x) => x;
// ^
@@ -18,7 +19,8 @@
return (core::int* x) → core::int* => x;
}
static method b() → asy::Future<(core::int*) →* core::int*>* async {
- return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/top_level_return_and_yield.dart:18:36: Error: A value of type 'dynamic Function(dynamic)' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
+ return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/top_level_return_and_yield.dart:18:36: Error: A value of type 'Future<dynamic Function(dynamic)>' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
+ - 'Future' is from 'dart:async'.
- 'FutureOr' is from 'dart:async'.
return /*@ returnType=dynamic */ (/*@ type=dynamic */ x) => x;
^" in ((dynamic x) → dynamic => x) as{TypeError} asy::FutureOr<(core::int*) →* core::int*>*;
diff --git a/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.strong.transformed.expect
index 135c992..9ebedc0 100644
--- a/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.strong.transformed.expect
@@ -2,7 +2,8 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/top_level_return_and_yield.dart:18:36: Error: A value of type 'dynamic Function(dynamic)' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
+// pkg/front_end/testcases/inference/top_level_return_and_yield.dart:18:36: Error: A value of type 'Future<dynamic Function(dynamic)>' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
+// - 'Future' is from 'dart:async'.
// - 'FutureOr' is from 'dart:async'.
// return /*@ returnType=dynamic */ (/*@ type=dynamic */ x) => x;
// ^
@@ -29,7 +30,8 @@
try {
#L1:
{
- :return_value = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/top_level_return_and_yield.dart:18:36: Error: A value of type 'dynamic Function(dynamic)' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
+ :return_value = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/top_level_return_and_yield.dart:18:36: Error: A value of type 'Future<dynamic Function(dynamic)>' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
+ - 'Future' is from 'dart:async'.
- 'FutureOr' is from 'dart:async'.
return /*@ returnType=dynamic */ (/*@ type=dynamic */ x) => x;
^" in ((dynamic x) → dynamic => x) as{TypeError} asy::FutureOr<(core::int*) →* core::int*>*;
diff --git a/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.textual_outline.expect b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.textual_outline.expect
new file mode 100644
index 0000000..505dfb3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+import 'dart:async';
+
+typedef int IntToInt(int i);
+IntToInt a() {}
+Future<IntToInt> b() async {}
+Iterable<IntToInt> c() sync* {}
+Iterable<IntToInt> d() sync* {}
+Stream<IntToInt> e() async* {}
+Stream<IntToInt> f() async* {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1047aa8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+import 'dart:async';
+
+Future<IntToInt> b() async {}
+IntToInt a() {}
+Iterable<IntToInt> c() sync* {}
+Iterable<IntToInt> d() sync* {}
+Stream<IntToInt> e() async* {}
+Stream<IntToInt> f() async* {}
+main() {}
+typedef int IntToInt(int i);
diff --git a/pkg/front_end/testcases/inference/toplevel_inference_toplevel_var.dart.textual_outline.expect b/pkg/front_end/testcases/inference/toplevel_inference_toplevel_var.dart.textual_outline.expect
new file mode 100644
index 0000000..8a7c345
--- /dev/null
+++ b/pkg/front_end/testcases/inference/toplevel_inference_toplevel_var.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+var i = 0;
+main() {}
diff --git a/pkg/front_end/testcases/inference/toplevel_inference_toplevel_var.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/toplevel_inference_toplevel_var.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..13c449d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/toplevel_inference_toplevel_var.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+var i = 0;
diff --git a/pkg/front_end/testcases/inference/try_catch.dart.textual_outline.expect b/pkg/front_end/testcases/inference/try_catch.dart.textual_outline.expect
new file mode 100644
index 0000000..e8f8435
--- /dev/null
+++ b/pkg/front_end/testcases/inference/try_catch.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C {}
+
+class D {}
+
+class E {}
+
+void test(void f()) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/try_catch.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/try_catch.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..19f476f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/try_catch.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C {}
+
+class D {}
+
+class E {}
+
+main() {}
+void test(void f()) {}
diff --git a/pkg/front_end/testcases/inference/try_catch_finally.dart.textual_outline.expect b/pkg/front_end/testcases/inference/try_catch_finally.dart.textual_outline.expect
new file mode 100644
index 0000000..e8f8435
--- /dev/null
+++ b/pkg/front_end/testcases/inference/try_catch_finally.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C {}
+
+class D {}
+
+class E {}
+
+void test(void f()) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/try_catch_finally.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/try_catch_finally.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..19f476f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/try_catch_finally.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C {}
+
+class D {}
+
+class E {}
+
+main() {}
+void test(void f()) {}
diff --git a/pkg/front_end/testcases/inference/try_catch_promotion.dart.textual_outline.expect b/pkg/front_end/testcases/inference/try_catch_promotion.dart.textual_outline.expect
new file mode 100644
index 0000000..a9c0032
--- /dev/null
+++ b/pkg/front_end/testcases/inference/try_catch_promotion.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C {}
+
+class D extends C {}
+
+class E extends StackTrace {}
+
+void test(void f()) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/try_catch_promotion.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/try_catch_promotion.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..595703f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/try_catch_promotion.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C {}
+
+class D extends C {}
+
+class E extends StackTrace {}
+
+main() {}
+void test(void f()) {}
diff --git a/pkg/front_end/testcases/inference/try_finally.dart.textual_outline.expect b/pkg/front_end/testcases/inference/try_finally.dart.textual_outline.expect
new file mode 100644
index 0000000..4323848
--- /dev/null
+++ b/pkg/front_end/testcases/inference/try_finally.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+void test(void f()) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/try_finally.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/try_finally.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6847854
--- /dev/null
+++ b/pkg/front_end/testcases/inference/try_finally.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+void test(void f()) {}
diff --git a/pkg/front_end/testcases/inference/type_cast.dart.textual_outline.expect b/pkg/front_end/testcases/inference/type_cast.dart.textual_outline.expect
new file mode 100644
index 0000000..eccaf58
--- /dev/null
+++ b/pkg/front_end/testcases/inference/type_cast.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+class A<T> {}
+
+class B<T> extends A<T> {
+ foo() {}
+}
+
+A<num> a = new B<int>();
+var b = (a as B<int>);
+main() {}
diff --git a/pkg/front_end/testcases/inference/type_cast.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/type_cast.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5483162
--- /dev/null
+++ b/pkg/front_end/testcases/inference/type_cast.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+A<num> a = new B<int>();
+
+class A<T> {}
+
+class B<T> extends A<T> {
+ foo() {}
+}
+
+main() {}
+var b = (a as B<int>);
diff --git a/pkg/front_end/testcases/inference/type_promotion_ignores_local_functions.dart.textual_outline.expect b/pkg/front_end/testcases/inference/type_promotion_ignores_local_functions.dart.textual_outline.expect
new file mode 100644
index 0000000..0c1f1fe
--- /dev/null
+++ b/pkg/front_end/testcases/inference/type_promotion_ignores_local_functions.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+typedef int FunctionReturningInt();
+main() {}
diff --git a/pkg/front_end/testcases/inference/type_promotion_ignores_local_functions.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/type_promotion_ignores_local_functions.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..350cc2e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/type_promotion_ignores_local_functions.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+typedef int FunctionReturningInt();
diff --git a/pkg/front_end/testcases/inference/type_promotion_not_and_not.dart.textual_outline.expect b/pkg/front_end/testcases/inference/type_promotion_not_and_not.dart.textual_outline.expect
new file mode 100644
index 0000000..0970cc2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/type_promotion_not_and_not.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+void f(Object x) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference/type_promotion_not_and_not.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/type_promotion_not_and_not.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e9a9e8c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/type_promotion_not_and_not.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+void f(Object x) {}
diff --git a/pkg/front_end/testcases/inference/type_promotion_simple.dart.textual_outline.expect b/pkg/front_end/testcases/inference/type_promotion_simple.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/type_promotion_simple.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/type_promotion_simple.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/type_promotion_simple.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/type_promotion_simple.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/type_promotion_stopped_by_access_in_a_closure.dart.textual_outline.expect b/pkg/front_end/testcases/inference/type_promotion_stopped_by_access_in_a_closure.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/type_promotion_stopped_by_access_in_a_closure.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/type_promotion_stopped_by_access_in_a_closure.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/type_promotion_stopped_by_access_in_a_closure.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/type_promotion_stopped_by_access_in_a_closure.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/type_promotion_stopped_by_assignment_in_scope.dart.textual_outline.expect b/pkg/front_end/testcases/inference/type_promotion_stopped_by_assignment_in_scope.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/type_promotion_stopped_by_assignment_in_scope.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/type_promotion_stopped_by_assignment_in_scope.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/type_promotion_stopped_by_assignment_in_scope.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/type_promotion_stopped_by_assignment_in_scope.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/type_promotion_stopped_by_mutation_in_a_closure.dart.textual_outline.expect b/pkg/front_end/testcases/inference/type_promotion_stopped_by_mutation_in_a_closure.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/type_promotion_stopped_by_mutation_in_a_closure.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/type_promotion_stopped_by_mutation_in_a_closure.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/type_promotion_stopped_by_mutation_in_a_closure.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/type_promotion_stopped_by_mutation_in_a_closure.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/unresolved_super.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unresolved_super.dart.textual_outline.expect
new file mode 100644
index 0000000..46441e1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unresolved_super.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+T f<T>() => null;
+
+class C {
+ void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/unresolved_super.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unresolved_super.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..46441e1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unresolved_super.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+T f<T>() => null;
+
+class C {
+ void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_closure_call.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_closure_call.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_closure_call.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_closure_call.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_closure_call.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_closure_call.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_explicit_dynamic_param.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_explicit_dynamic_param.dart.textual_outline.expect
new file mode 100644
index 0000000..94fe6c8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_explicit_dynamic_param.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C<T> {
+ C(T x());
+}
+
+var v = new C<dynamic>(() {
+ return 1;
+});
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_explicit_dynamic_param.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_explicit_dynamic_param.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..faaeac6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_explicit_dynamic_param.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C<T> {
+ C(T x());
+}
+
+main() {}
+var v = new C<dynamic>(() {
+ return 1;
+});
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_explicit_type_param.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_explicit_type_param.dart.textual_outline.expect
new file mode 100644
index 0000000..045c2e8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_explicit_type_param.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C<T> {
+ C(T x());
+}
+
+var v = new C<int>(() {
+ return 1;
+});
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_explicit_type_param.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_explicit_type_param.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7917d91
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_explicit_type_param.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C<T> {
+ C(T x());
+}
+
+main() {}
+var v = new C<int>(() {
+ return 1;
+});
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_implicit_type_param.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_implicit_type_param.dart.textual_outline.expect
new file mode 100644
index 0000000..db10511
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_implicit_type_param.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C<T> {
+ C(T x());
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_implicit_type_param.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_implicit_type_param.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..db10511
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_implicit_type_param.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C<T> {
+ C(T x());
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_no_type_param.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_no_type_param.dart.textual_outline.expect
new file mode 100644
index 0000000..77314e89
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_no_type_param.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C {
+ C(x());
+}
+
+var v = new C(() {
+ return 1;
+});
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_no_type_param.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_no_type_param.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b916948
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_no_type_param.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C {
+ C(x());
+}
+
+main() {}
+var v = new C(() {
+ return 1;
+});
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param.dart.textual_outline.expect
new file mode 100644
index 0000000..5426b5f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+List<T> f<T>(T g()) => <T>[g()];
+var v = f<dynamic>(() {
+ return 1;
+});
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..aed6c69
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+List<T> f<T>(T g()) => <T>[g()];
+main() {}
+var v = f<dynamic>(() {
+ return 1;
+});
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr1.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr1.dart.textual_outline.expect
new file mode 100644
index 0000000..584632f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr1.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+List<T> f<T>(T g()) => <T>[g()];
+var v = (f<dynamic>)( () { return 1; });
+main() { }
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr2.dart.textual_outline.expect
new file mode 100644
index 0000000..6fabe27
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr2.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+List<T> f<T>(T g()) => <T>[g()];
+var v = (f)<dynamic>(() {
+ return 1;
+});
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..99e882a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr2.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+List<T> f<T>(T g()) => <T>[g()];
+main() {}
+var v = (f)<dynamic>(() {
+ return 1;
+});
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param.dart.textual_outline.expect
new file mode 100644
index 0000000..3146638
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+List<T> f<T>(T g()) => <T>[g()];
+var v = f<int>(() {
+ return 1;
+});
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..df8a26a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+List<T> f<T>(T g()) => <T>[g()];
+main() {}
+var v = f<int>(() {
+ return 1;
+});
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr1.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr1.dart.textual_outline.expect
new file mode 100644
index 0000000..a966a2f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr1.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+List<T> f<T>(T g()) => <T>[g()];
+var v = (f<int>)( () { return 1; });
+main() { }
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr2.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr2.dart.textual_outline.expect
new file mode 100644
index 0000000..c7bca42
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr2.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+List<T> f<T>(T g()) => <T>[g()];
+var v = (f)<int>(() {
+ return 1;
+});
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f634c6a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr2.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+List<T> f<T>(T g()) => <T>[g()];
+main() {}
+var v = (f)<int>(() {
+ return 1;
+});
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_implicit_type_param.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_implicit_type_param.dart.textual_outline.expect
new file mode 100644
index 0000000..6104397
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_implicit_type_param.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+List<T> f<T>(T g()) => <T>[g()];
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_implicit_type_param.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_implicit_type_param.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..158c522b4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_implicit_type_param.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+List<T> f<T>(T g()) => <T>[g()];
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_implicit_type_param_via_expr.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_implicit_type_param_via_expr.dart.textual_outline.expect
new file mode 100644
index 0000000..6104397
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_implicit_type_param_via_expr.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+List<T> f<T>(T g()) => <T>[g()];
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_implicit_type_param_via_expr.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_implicit_type_param_via_expr.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..158c522b4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_implicit_type_param_via_expr.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+List<T> f<T>(T g()) => <T>[g()];
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_no_type_param.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_no_type_param.dart.textual_outline.expect
new file mode 100644
index 0000000..a0e3c88
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_no_type_param.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+double f(x) => 1.0;
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_no_type_param.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_no_type_param.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3fe047c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_no_type_param.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+double f(x) => 1.0;
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_no_type_param_via_expr.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_no_type_param_via_expr.dart.textual_outline.expect
new file mode 100644
index 0000000..a0e3c88
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_no_type_param_via_expr.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+double f(x) => 1.0;
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_no_type_param_via_expr.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_no_type_param_via_expr.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3fe047c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_no_type_param_via_expr.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+double f(x) => 1.0;
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_dynamic.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_dynamic.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_dynamic.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_dynamic.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_dynamic.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_dynamic.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_typed.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_typed.dart.textual_outline.expect
new file mode 100644
index 0000000..0286208
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_typed.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+typedef int F();
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_typed.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_typed.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..226c034
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_typed.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+typedef int F();
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_untyped.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_untyped.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_untyped.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_untyped.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_untyped.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_untyped.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_dynamic.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_dynamic.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_dynamic.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_dynamic.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_dynamic.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_dynamic.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_typed.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_typed.dart.textual_outline.expect
new file mode 100644
index 0000000..0286208
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_typed.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+typedef int F();
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_typed.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_typed.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..226c034
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_typed.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+typedef int F();
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_untyped.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_untyped.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_untyped.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_untyped.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_untyped.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_untyped.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_dynamic_param.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_dynamic_param.dart.textual_outline.expect
new file mode 100644
index 0000000..8f9363d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_dynamic_param.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+ List<T> f<T>(T g()) => <T>[g()];
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_dynamic_param.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_dynamic_param.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8f9363d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_dynamic_param.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+ List<T> f<T>(T g()) => <T>[g()];
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_type_param.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_type_param.dart.textual_outline.expect
new file mode 100644
index 0000000..8f9363d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_type_param.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+ List<T> f<T>(T g()) => <T>[g()];
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_type_param.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_type_param.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8f9363d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_type_param.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+ List<T> f<T>(T g()) => <T>[g()];
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_implicit_type_param.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_implicit_type_param.dart.textual_outline.expect
new file mode 100644
index 0000000..8f9363d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_implicit_type_param.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+ List<T> f<T>(T g()) => <T>[g()];
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_implicit_type_param.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_implicit_type_param.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8f9363d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_implicit_type_param.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+ List<T> f<T>(T g()) => <T>[g()];
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_no_type_param.dart.textual_outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_no_type_param.dart.textual_outline.expect
new file mode 100644
index 0000000..5dfe4b0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_no_type_param.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C {
+ double f(x) => 1.0;
+}
+
+var v = new C().f(() {
+ return 1;
+});
+main() {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_no_type_param.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_no_type_param.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..470fb87
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_no_type_param.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C {
+ double f(x) => 1.0;
+}
+
+main() {}
+var v = new C().f(() {
+ return 1;
+});
diff --git a/pkg/front_end/testcases/inference/void_return_type_subtypes_dynamic.dart.textual_outline.expect b/pkg/front_end/testcases/inference/void_return_type_subtypes_dynamic.dart.textual_outline.expect
new file mode 100644
index 0000000..ffe2084
--- /dev/null
+++ b/pkg/front_end/testcases/inference/void_return_type_subtypes_dynamic.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+T run<T>(T f()) {}
+void printRunning() {}
+var x = run<dynamic>(printRunning);
+main() {}
diff --git a/pkg/front_end/testcases/inference/void_return_type_subtypes_dynamic.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference/void_return_type_subtypes_dynamic.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..65a862b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/void_return_type_subtypes_dynamic.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+T run<T>(T f()) {}
+main() {}
+var x = run<dynamic>(printRunning);
+void printRunning() {}
diff --git a/pkg/front_end/testcases/inference_new/const_invocation.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/const_invocation.dart.textual_outline.expect
new file mode 100644
index 0000000..e44b24c
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/const_invocation.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+library test;
+
+typedef V F<U, V>(U u);
+
+class Foo<T> {
+ Bar<T> get v1 => const Bar();
+ Bar<List<T>> get v2 => const Bar();
+ Bar<F<T, T>> get v3 => const Bar();
+ Bar<F<F<T, T>, T>> get v4 => const Bar();
+ List<T> get v5 => const [];
+ List<F<T, T>> get v6 => const [];
+ Map<T, T> get v7 => const {};
+ Map<F<T, T>, T> get v8 => const {};
+ Map<T, F<T, T>> get v9 => const {};
+}
+
+class Bar<T> {
+ const Bar();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/const_invocation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/const_invocation.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ebcecde
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/const_invocation.dart.textual_outline_modelled.expect
@@ -0,0 +1,20 @@
+library test;
+
+class Bar<T> {
+ const Bar();
+}
+
+class Foo<T> {
+ Bar<F<F<T, T>, T>> get v4 => const Bar();
+ Bar<F<T, T>> get v3 => const Bar();
+ Bar<List<T>> get v2 => const Bar();
+ Bar<T> get v1 => const Bar();
+ List<F<T, T>> get v6 => const [];
+ List<T> get v5 => const [];
+ Map<F<T, T>, T> get v8 => const {};
+ Map<T, F<T, T>> get v9 => const {};
+ Map<T, T> get v7 => const {};
+}
+
+main() {}
+typedef V F<U, V>(U u);
diff --git a/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.textual_outline.expect
new file mode 100644
index 0000000..05229f3
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+class A {
+ T f<T>(T t) => t;
+ int g(dynamic i) => 0;
+}
+
+var a = new A();
+var b = () => a.f(c);
+var c = () => a.f(b);
+var d = () => a.f(e);
+var e = () => a.g(d);
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0f55a46
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+class A {
+ T f<T>(T t) => t;
+ int g(dynamic i) => 0;
+}
+
+main() {}
+var a = new A();
+var b = () => a.f(c);
+var c = () => a.f(b);
+var d = () => a.f(e);
+var e = () => a.g(d);
diff --git a/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.textual_outline.expect
new file mode 100644
index 0000000..db69969
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+int intValue = 0;
+num numValue = 0;
+double doubleValue = 0.0;
+var a = () => intValue + b;
+var b = a();
+var c = () => numValue + d;
+var d = c();
+var e = () => doubleValue + f;
+var f = e();
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5009f27
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+double doubleValue = 0.0;
+int intValue = 0;
+main() {}
+num numValue = 0;
+var a = () => intValue + b;
+var b = a();
+var c = () => numValue + d;
+var d = c();
+var e = () => doubleValue + f;
+var f = e();
diff --git a/pkg/front_end/testcases/inference_new/do_loop.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/do_loop.dart.textual_outline.expect
new file mode 100644
index 0000000..cdb201d
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/do_loop.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+T f<T>() => null;
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/do_loop.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/do_loop.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b66d908
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/do_loop.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+T f<T>() => null;
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference_new/downwards_inference_inside_top_level.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/downwards_inference_inside_top_level.dart.textual_outline.expect
new file mode 100644
index 0000000..d781f4d
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/downwards_inference_inside_top_level.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+class A {
+ B<int> b;
+}
+
+class B<T> {
+ B(T x);
+}
+
+var t3 = [new B(3)];
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/downwards_inference_inside_top_level.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/downwards_inference_inside_top_level.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..56d49b4
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/downwards_inference_inside_top_level.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+class A {
+ B<int> b;
+}
+
+class B<T> {
+ B(T x);
+}
+
+main() {}
+var t3 = [new B(3)];
diff --git a/pkg/front_end/testcases/inference_new/downwards_inference_inside_top_level_2.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/downwards_inference_inside_top_level_2.dart.textual_outline.expect
new file mode 100644
index 0000000..c5e4a4c
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/downwards_inference_inside_top_level_2.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class A<T> {
+ A(T x);
+}
+
+var t2 = [new A(2)];
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/downwards_inference_inside_top_level_2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/downwards_inference_inside_top_level_2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4da7ccb
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/downwards_inference_inside_top_level_2.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class A<T> {
+ A(T x);
+}
+
+main() {}
+var t2 = [new A(2)];
diff --git a/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.textual_outline.expect
new file mode 100644
index 0000000..fa0576a
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+class A {
+ var x = () => new B().x;
+ var y = () => new B().x;
+}
+
+class B extends A {
+ var x;
+ var y;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fa0576a
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+class A {
+ var x = () => new B().x;
+ var y = () => new B().x;
+}
+
+class B extends A {
+ var x;
+ var y;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/for_each_identifier_downwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/for_each_identifier_downwards.dart.textual_outline.expect
new file mode 100644
index 0000000..81dec4b
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/for_each_identifier_downwards.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+library test;
+
+T f<T>() => null;
+
+class A {}
+
+A aTopLevel;
+void set aTopLevelSetter(A value) {}
+
+class C {
+ A aField;
+ void set aSetter(A value) {}
+ void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/for_each_identifier_downwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/for_each_identifier_downwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..492e0aa
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/for_each_identifier_downwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+A aTopLevel;
+T f<T>() => null;
+
+class A {}
+
+class C {
+ A aField;
+ void set aSetter(A value) {}
+ void test() {}
+}
+
+main() {}
+void set aTopLevelSetter(A value) {}
diff --git a/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.textual_outline.expect
new file mode 100644
index 0000000..178286b
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+test() async {}
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4791aa1
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+test() async {}
diff --git a/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.textual_outline.expect
new file mode 100644
index 0000000..d166bc9
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+import 'dart:async';
+
+T f<T>() => null;
+
+class A {}
+
+class B extends A {}
+
+test() async {}
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f55cead
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+import 'dart:async';
+
+T f<T>() => null;
+
+class A {}
+
+class B extends A {}
+
+main() {}
+test() async {}
diff --git a/pkg/front_end/testcases/inference_new/indexed_assign_combiner.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/indexed_assign_combiner.dart.textual_outline.expect
new file mode 100644
index 0000000..a7060ac
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/indexed_assign_combiner.dart.textual_outline.expect
@@ -0,0 +1,31 @@
+library test;
+
+T f<T>() => null;
+
+class A {
+ C operator +(int value) => null;
+ C operator *(D value) => null;
+}
+
+class B {
+ E operator +(int value) => null;
+ E operator *(F value) => null;
+}
+
+class C extends B {}
+
+class D {}
+
+class E {}
+
+class F {}
+
+class G {
+ A operator [](int i) => null;
+ void operator []=(int i, B value) {}
+}
+
+void test1(G g) {}
+void test2(G g) {}
+void test3(G g) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/indexed_assign_combiner.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/indexed_assign_combiner.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0e78520
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/indexed_assign_combiner.dart.textual_outline_modelled.expect
@@ -0,0 +1,31 @@
+library test;
+
+T f<T>() => null;
+
+class A {
+ C operator *(D value) => null;
+ C operator +(int value) => null;
+}
+
+class B {
+ E operator *(F value) => null;
+ E operator +(int value) => null;
+}
+
+class C extends B {}
+
+class D {}
+
+class E {}
+
+class F {}
+
+class G {
+ A operator [](int i) => null;
+ void operator []=(int i, B value) {}
+}
+
+main() {}
+void test1(G g) {}
+void test2(G g) {}
+void test3(G g) {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this.dart.textual_outline.expect
new file mode 100644
index 0000000..cce1286
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+library test;
+
+class A {}
+
+class B extends A {
+ A operator +(C v) => null;
+ B operator -(int i) => null;
+ B operator *(B v) => null;
+ C operator &(A v) => null;
+}
+
+class C extends B {}
+
+T f<T>() => null;
+
+class Test {
+ B member;
+ void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fedf127
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+library test;
+
+T f<T>() => null;
+
+class A {}
+
+class B extends A {
+ A operator +(C v) => null;
+ B operator *(B v) => null;
+ B operator -(int i) => null;
+ C operator &(A v) => null;
+}
+
+class C extends B {}
+
+class Test {
+ B member;
+ void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this_upwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this_upwards.dart.textual_outline.expect
new file mode 100644
index 0000000..5aea77f
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this_upwards.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+library test;
+
+int getInt() => 0;
+num getNum() => 0;
+double getDouble() => 0.0;
+
+class Test1 {
+ int t;
+ void test() {}
+}
+
+class Test2 {
+ num t;
+ void test() {}
+}
+
+class Test3 {
+ double t;
+ void test3() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this_upwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this_upwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c07ae2b
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this_upwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+library test;
+
+class Test1 {
+ int t;
+ void test() {}
+}
+
+class Test2 {
+ num t;
+ void test() {}
+}
+
+class Test3 {
+ double t;
+ void test3() {}
+}
+
+double getDouble() => 0.0;
+int getInt() => 0;
+main() {}
+num getNum() => 0;
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index.dart.textual_outline.expect
new file mode 100644
index 0000000..c70181a
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+List<double> a = <double>[];
+var b = (a[0] = 1.0);
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..89115d7
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+List<double> a = <double>[];
+main() {}
+var b = (a[0] = 1.0);
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_full.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_full.dart.textual_outline.expect
new file mode 100644
index 0000000..b37e03c
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_full.dart.textual_outline.expect
@@ -0,0 +1,24 @@
+library test;
+
+class Index {}
+
+class A {}
+
+class B extends A {
+ A operator +(C v) => null;
+ B operator -(int i) => null;
+ B operator *(B v) => null;
+ C operator &(A v) => null;
+}
+
+class C extends B {}
+
+T f<T>() => null;
+
+class Test {
+ B operator [](Index i) => null;
+ void operator []=(Index i, B v) {}
+ void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_full.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_full.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e02d004
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_full.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+library test;
+
+T f<T>() => null;
+
+class A {}
+
+class B extends A {
+ A operator +(C v) => null;
+ B operator *(B v) => null;
+ B operator -(int i) => null;
+ C operator &(A v) => null;
+}
+
+class C extends B {}
+
+class Index {}
+
+class Test {
+ B operator [](Index i) => null;
+ void operator []=(Index i, B v) {}
+ void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_set_vs_get.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_set_vs_get.dart.textual_outline.expect
new file mode 100644
index 0000000..d7ce8b5
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_set_vs_get.dart.textual_outline.expect
@@ -0,0 +1,31 @@
+library test;
+
+class Index {}
+
+class A {
+ C operator +(F v) => null;
+ C operator -(int i) => null;
+}
+
+class B extends A {
+ D operator +(E v) => null;
+ D operator -(int i) => null;
+}
+
+class C extends B {}
+
+class D extends C {}
+
+class E extends D {}
+
+class F extends E {}
+
+T f<T>() => null;
+
+class Test {
+ B operator [](Index i) => null;
+ void operator []=(Index i, A v) {}
+ void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_set_vs_get.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_set_vs_get.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..82d9240
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_set_vs_get.dart.textual_outline_modelled.expect
@@ -0,0 +1,31 @@
+library test;
+
+T f<T>() => null;
+
+class A {
+ C operator +(F v) => null;
+ C operator -(int i) => null;
+}
+
+class B extends A {
+ D operator +(E v) => null;
+ D operator -(int i) => null;
+}
+
+class C extends B {}
+
+class D extends C {}
+
+class E extends D {}
+
+class F extends E {}
+
+class Index {}
+
+class Test {
+ B operator [](Index i) => null;
+ void operator []=(Index i, A v) {}
+ void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_super.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super.dart.textual_outline.expect
new file mode 100644
index 0000000..0082739
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super.dart.textual_outline.expect
@@ -0,0 +1,27 @@
+library test;
+
+class Index {}
+
+class A {}
+
+class B extends A {
+ A operator +(C v) => null;
+ B operator -(int i) => null;
+ B operator *(B v) => null;
+ C operator &(A v) => null;
+}
+
+class C extends B {}
+
+T f<T>() => null;
+
+class Base {
+ B operator [](Index i) => null;
+ void operator []=(Index i, B v) {}
+}
+
+class Test extends Base {
+ void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_super.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3153d49
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super.dart.textual_outline_modelled.expect
@@ -0,0 +1,27 @@
+library test;
+
+T f<T>() => null;
+
+class A {}
+
+class B extends A {
+ A operator +(C v) => null;
+ B operator *(B v) => null;
+ B operator -(int i) => null;
+ C operator &(A v) => null;
+}
+
+class Base {
+ B operator [](Index i) => null;
+ void operator []=(Index i, B v) {}
+}
+
+class C extends B {}
+
+class Index {}
+
+class Test extends Base {
+ void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart.textual_outline.expect
new file mode 100644
index 0000000..532c44a
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart.textual_outline.expect
@@ -0,0 +1,50 @@
+library test;
+
+int getInt() => 0;
+num getNum() => 0;
+double getDouble() => 0.0;
+
+abstract class Base<T, U> {
+ T operator [](String s) => getValue(s);
+ void operator []=(String s, U v) => setValue(s, v);
+ T getValue(String s);
+ void setValue(String s, U v);
+}
+
+abstract class Test1 extends Base<int, int> {
+ void test() {}
+}
+
+abstract class Test2 extends Base<int, num> {
+ void test() {}
+}
+
+abstract class Test3 extends Base<int, double> {
+ void test() {}
+}
+
+abstract class Test4 extends Base<num, int> {
+ void test() {}
+}
+
+abstract class Test5 extends Base<num, num> {
+ void test() {}
+}
+
+abstract class Test6 extends Base<num, double> {
+ void test() {}
+}
+
+abstract class Test7 extends Base<double, int> {
+ void test() {}
+}
+
+abstract class Test8 extends Base<double, num> {
+ void test() {}
+}
+
+abstract class Test9 extends Base<double, double> {
+ void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8860e7d
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,49 @@
+library test;
+
+abstract class Base<T, U> {
+ T getValue(String s);
+ T operator [](String s) => getValue(s);
+ void operator []=(String s, U v) => setValue(s, v);
+ void setValue(String s, U v);
+}
+
+abstract class Test1 extends Base<int, int> {
+ void test() {}
+}
+
+abstract class Test2 extends Base<int, num> {
+ void test() {}
+}
+
+abstract class Test3 extends Base<int, double> {
+ void test() {}
+}
+
+abstract class Test4 extends Base<num, int> {
+ void test() {}
+}
+
+abstract class Test5 extends Base<num, num> {
+ void test() {}
+}
+
+abstract class Test6 extends Base<num, double> {
+ void test() {}
+}
+
+abstract class Test7 extends Base<double, int> {
+ void test() {}
+}
+
+abstract class Test8 extends Base<double, num> {
+ void test() {}
+}
+
+abstract class Test9 extends Base<double, double> {
+ void test() {}
+}
+
+double getDouble() => 0.0;
+int getInt() => 0;
+main() {}
+num getNum() => 0;
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_this.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this.dart.textual_outline.expect
new file mode 100644
index 0000000..b37e03c
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this.dart.textual_outline.expect
@@ -0,0 +1,24 @@
+library test;
+
+class Index {}
+
+class A {}
+
+class B extends A {
+ A operator +(C v) => null;
+ B operator -(int i) => null;
+ B operator *(B v) => null;
+ C operator &(A v) => null;
+}
+
+class C extends B {}
+
+T f<T>() => null;
+
+class Test {
+ B operator [](Index i) => null;
+ void operator []=(Index i, B v) {}
+ void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_this.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e02d004
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+library test;
+
+T f<T>() => null;
+
+class A {}
+
+class B extends A {
+ A operator +(C v) => null;
+ B operator *(B v) => null;
+ B operator -(int i) => null;
+ C operator &(A v) => null;
+}
+
+class C extends B {}
+
+class Index {}
+
+class Test {
+ B operator [](Index i) => null;
+ void operator []=(Index i, B v) {}
+ void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart.textual_outline.expect
new file mode 100644
index 0000000..d4cf186
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart.textual_outline.expect
@@ -0,0 +1,61 @@
+library test;
+
+int getInt() => 0;
+num getNum() => 0;
+double getDouble() => 0.0;
+
+abstract class Test1 {
+ int operator [](String s);
+ void operator []=(String s, int v);
+ void test() {}
+}
+
+abstract class Test2 {
+ int operator [](String s);
+ void operator []=(String s, num v);
+ void test() {}
+}
+
+abstract class Test3 {
+ int operator [](String s);
+ void operator []=(String s, double v);
+ void test() {}
+}
+
+abstract class Test4 {
+ num operator [](String s);
+ void operator []=(String s, int v);
+ void test() {}
+}
+
+abstract class Test5 {
+ num operator [](String s);
+ void operator []=(String s, num v);
+ void test() {}
+}
+
+abstract class Test6 {
+ num operator [](String s);
+ void operator []=(String s, double v);
+ void test() {}
+}
+
+abstract class Test7 {
+ double operator [](String s);
+ void operator []=(String s, int v);
+ void test() {}
+}
+
+abstract class Test8 {
+ double operator [](String s);
+ void operator []=(String s, num v);
+ void test() {}
+}
+
+abstract class Test9 {
+ double operator [](String s);
+ void operator []=(String s, double v);
+ void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..97ebc39
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,60 @@
+library test;
+
+abstract class Test1 {
+ int operator [](String s);
+ void operator []=(String s, int v);
+ void test() {}
+}
+
+abstract class Test2 {
+ int operator [](String s);
+ void operator []=(String s, num v);
+ void test() {}
+}
+
+abstract class Test3 {
+ int operator [](String s);
+ void operator []=(String s, double v);
+ void test() {}
+}
+
+abstract class Test4 {
+ num operator [](String s);
+ void operator []=(String s, int v);
+ void test() {}
+}
+
+abstract class Test5 {
+ num operator [](String s);
+ void operator []=(String s, num v);
+ void test() {}
+}
+
+abstract class Test6 {
+ num operator [](String s);
+ void operator []=(String s, double v);
+ void test() {}
+}
+
+abstract class Test7 {
+ double operator [](String s);
+ void operator []=(String s, int v);
+ void test() {}
+}
+
+abstract class Test8 {
+ double operator [](String s);
+ void operator []=(String s, num v);
+ void test() {}
+}
+
+abstract class Test9 {
+ double operator [](String s);
+ void operator []=(String s, double v);
+ void test() {}
+}
+
+double getDouble() => 0.0;
+int getInt() => 0;
+main() {}
+num getNum() => 0;
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart.textual_outline.expect
new file mode 100644
index 0000000..3217b84
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+library test;
+
+int getInt() => 0;
+num getNum() => 0;
+double getDouble() => 0.0;
+
+abstract class Test<T, U> {
+ T operator [](String s);
+ void operator []=(String s, U v);
+}
+
+void test1(Test<int, int> t) {}
+void test2(Test<int, num> t) {}
+void test3(Test<int, double> t) {}
+void test4(Test<num, int> t) {}
+void test5(Test<num, num> t) {}
+void test6(Test<num, double> t) {}
+void test7(Test<double, int> t) {}
+void test8(Test<double, num> t) {}
+void test9(Test<double, double> t) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..db75467
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,20 @@
+library test;
+
+abstract class Test<T, U> {
+ T operator [](String s);
+ void operator []=(String s, U v);
+}
+
+double getDouble() => 0.0;
+int getInt() => 0;
+main() {}
+num getNum() => 0;
+void test1(Test<int, int> t) {}
+void test2(Test<int, num> t) {}
+void test3(Test<int, double> t) {}
+void test4(Test<num, int> t) {}
+void test5(Test<num, num> t) {}
+void test6(Test<num, double> t) {}
+void test7(Test<double, int> t) {}
+void test8(Test<double, num> t) {}
+void test9(Test<double, double> t) {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart.textual_outline.expect
new file mode 100644
index 0000000..54818ba
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+library test;
+
+class A {}
+
+class B extends A {
+ A operator +(C v) => null;
+ B operator -(int i) => null;
+ B operator *(B v) => null;
+ C operator &(A v) => null;
+}
+
+class C extends B {}
+
+T f<T>() => null;
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..370d98d
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+library test;
+
+T f<T>() => null;
+
+class A {}
+
+class B extends A {
+ A operator +(C v) => null;
+ B operator *(B v) => null;
+ B operator -(int i) => null;
+ C operator &(A v) => null;
+}
+
+class C extends B {}
+
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart.textual_outline.expect
new file mode 100644
index 0000000..d9659ac
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+int getInt() => 0;
+num getNum() => 0;
+double getDouble() => 0.0;
+void test1(int t) {}
+void test2(num t) {}
+void test3(double t) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f01f8e9
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+double getDouble() => 0.0;
+int getInt() => 0;
+main() {}
+num getNum() => 0;
+void test1(int t) {}
+void test2(num t) {}
+void test3(double t) {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property.dart.textual_outline.expect
new file mode 100644
index 0000000..578332f
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+class A {
+ int f;
+}
+
+var v_assign = (new A().f = 1);
+var v_plus = (new A().f += 1);
+var v_minus = (new A().f -= 1);
+var v_multiply = (new A().f *= 1);
+var v_prefix_pp = (++new A().f);
+var v_prefix_mm = (--new A().f);
+var v_postfix_pp = (new A().f++);
+var v_postfix_mm = (new A().f--);
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..35df05a
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+class A {
+ int f;
+}
+
+main() {}
+var v_assign = (new A().f = 1);
+var v_minus = (new A().f -= 1);
+var v_multiply = (new A().f *= 1);
+var v_plus = (new A().f += 1);
+var v_postfix_mm = (new A().f--);
+var v_postfix_pp = (new A().f++);
+var v_prefix_mm = (--new A().f);
+var v_prefix_pp = (++new A().f);
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart.textual_outline.expect
new file mode 100644
index 0000000..7edc4ca
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+library test;
+
+class A {
+ int operator +(other) => 1;
+ double operator -(other) => 2.0;
+}
+
+class B {
+ A a;
+}
+
+var v_prefix_pp = (++new B().a);
+var v_prefix_mm = (--new B().a);
+var v_postfix_pp = (new B().a++);
+var v_postfix_mm = (new B().a--);
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..50cda50
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+library test;
+
+class A {
+ double operator -(other) => 2.0;
+ int operator +(other) => 1;
+}
+
+class B {
+ A a;
+}
+
+main() {}
+var v_postfix_mm = (new B().a--);
+var v_postfix_pp = (new B().a++);
+var v_prefix_mm = (--new B().a);
+var v_prefix_pp = (++new B().a);
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_full.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_full.dart.textual_outline.expect
new file mode 100644
index 0000000..f1916a0
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_full.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+library test;
+
+class A {}
+
+class B extends A {
+ A operator +(C v) => null;
+ B operator -(int i) => null;
+ B operator *(B v) => null;
+ C operator &(A v) => null;
+}
+
+class C extends B {}
+
+T f<T>() => null;
+
+class Test {
+ B member;
+ static void test(Test t) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_full.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_full.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1ddd4b1
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_full.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+library test;
+
+T f<T>() => null;
+
+class A {}
+
+class B extends A {
+ A operator +(C v) => null;
+ B operator *(B v) => null;
+ B operator -(int i) => null;
+ C operator &(A v) => null;
+}
+
+class C extends B {}
+
+class Test {
+ B member;
+ static void test(Test t) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart.textual_outline.expect
new file mode 100644
index 0000000..f1916a0
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+library test;
+
+class A {}
+
+class B extends A {
+ A operator +(C v) => null;
+ B operator -(int i) => null;
+ B operator *(B v) => null;
+ C operator &(A v) => null;
+}
+
+class C extends B {}
+
+T f<T>() => null;
+
+class Test {
+ B member;
+ static void test(Test t) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1ddd4b1
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+library test;
+
+T f<T>() => null;
+
+class A {}
+
+class B extends A {
+ A operator +(C v) => null;
+ B operator *(B v) => null;
+ B operator -(int i) => null;
+ C operator &(A v) => null;
+}
+
+class C extends B {}
+
+class Test {
+ B member;
+ static void test(Test t) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart.textual_outline.expect
new file mode 100644
index 0000000..0757142
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+library test;
+
+int getInt() => 0;
+num getNum() => 0;
+double getDouble() => 0.0;
+
+class Test1 {
+ int prop;
+ static void test(Test1 t) {}
+}
+
+class Test2 {
+ num prop;
+ static void test(Test2 t) {}
+}
+
+class Test3 {
+ double prop;
+ static void test3(Test3 t) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..265e693
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+library test;
+
+class Test1 {
+ int prop;
+ static void test(Test1 t) {}
+}
+
+class Test2 {
+ num prop;
+ static void test(Test2 t) {}
+}
+
+class Test3 {
+ double prop;
+ static void test3(Test3 t) {}
+}
+
+double getDouble() => 0.0;
+int getInt() => 0;
+main() {}
+num getNum() => 0;
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_super.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_super.dart.textual_outline.expect
new file mode 100644
index 0000000..2d1227e
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_super.dart.textual_outline.expect
@@ -0,0 +1,24 @@
+library test;
+
+class A {}
+
+class B extends A {
+ A operator +(C v) => null;
+ B operator -(int i) => null;
+ B operator *(B v) => null;
+ C operator &(A v) => null;
+}
+
+class C extends B {}
+
+T f<T>() => null;
+
+class Base {
+ B member;
+}
+
+class Test extends Base {
+ void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_super.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_super.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cdf4959
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_super.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+library test;
+
+T f<T>() => null;
+
+class A {}
+
+class B extends A {
+ A operator +(C v) => null;
+ B operator *(B v) => null;
+ B operator -(int i) => null;
+ C operator &(A v) => null;
+}
+
+class Base {
+ B member;
+}
+
+class C extends B {}
+
+class Test extends Base {
+ void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_super_upwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_super_upwards.dart.textual_outline.expect
new file mode 100644
index 0000000..31af0c8
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_super_upwards.dart.textual_outline.expect
@@ -0,0 +1,25 @@
+library test;
+
+int getInt() => 0;
+num getNum() => 0;
+double getDouble() => 0.0;
+
+class Base {
+ int intProp;
+ num numProp;
+ double doubleProp;
+}
+
+class Test1 extends Base {
+ void test() {}
+}
+
+class Test2 extends Base {
+ void test() {}
+}
+
+class Test3 extends Base {
+ void test3() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_super_upwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_super_upwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5d5e219
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_super_upwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+library test;
+
+class Base {
+ double doubleProp;
+ int intProp;
+ num numProp;
+}
+
+class Test1 extends Base {
+ void test() {}
+}
+
+class Test2 extends Base {
+ void test() {}
+}
+
+class Test3 extends Base {
+ void test3() {}
+}
+
+double getDouble() => 0.0;
+int getInt() => 0;
+main() {}
+num getNum() => 0;
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_upwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_upwards.dart.textual_outline.expect
new file mode 100644
index 0000000..0757142
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_upwards.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+library test;
+
+int getInt() => 0;
+num getNum() => 0;
+double getDouble() => 0.0;
+
+class Test1 {
+ int prop;
+ static void test(Test1 t) {}
+}
+
+class Test2 {
+ num prop;
+ static void test(Test2 t) {}
+}
+
+class Test3 {
+ double prop;
+ static void test3(Test3 t) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_upwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_upwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..265e693
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_upwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+library test;
+
+class Test1 {
+ int prop;
+ static void test(Test1 t) {}
+}
+
+class Test2 {
+ num prop;
+ static void test(Test2 t) {}
+}
+
+class Test3 {
+ double prop;
+ static void test3(Test3 t) {}
+}
+
+double getDouble() => 0.0;
+int getInt() => 0;
+main() {}
+num getNum() => 0;
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_ref.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_ref.dart.textual_outline.expect
new file mode 100644
index 0000000..433e168
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_ref.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+class A {
+ int f;
+}
+
+A a = new A();
+var b = (a.f = 1);
+var c = 0;
+var d = (c = 1);
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_ref.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_ref.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d1ca26e
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_ref.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+A a = new A();
+
+class A {
+ int f;
+}
+
+main() {}
+var b = (a.f = 1);
+var c = 0;
+var d = (c = 1);
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_static.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_static.dart.textual_outline.expect
new file mode 100644
index 0000000..3ee6268
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_static.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+library test;
+
+class A {}
+
+class B extends A {
+ A operator +(C v) => null;
+ B operator -(int i) => null;
+ B operator *(B v) => null;
+ C operator &(A v) => null;
+ static B staticVariable;
+}
+
+class C extends B {}
+
+T f<T>() => null;
+B topLevelVariable;
+void test_topLevelVariable() {}
+void test_staticVariable() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_static.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_static.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..667b734
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_static.dart.textual_outline_modelled.expect
@@ -0,0 +1,20 @@
+library test;
+
+B topLevelVariable;
+T f<T>() => null;
+
+class A {}
+
+class B extends A {
+ A operator +(C v) => null;
+ B operator *(B v) => null;
+ B operator -(int i) => null;
+ C operator &(A v) => null;
+ static B staticVariable;
+}
+
+class C extends B {}
+
+main() {}
+void test_staticVariable() {}
+void test_topLevelVariable() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_static_upwards.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_static_upwards.dart.textual_outline.expect
new file mode 100644
index 0000000..13362e8
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_static_upwards.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+int getInt() => 0;
+num getNum() => 0;
+double getDouble() => 0.0;
+int topLevelInt;
+num topLevelNum;
+double topLevelDouble;
+void test1() {}
+void test2() {}
+void test3() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_static_upwards.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_static_upwards.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2b31b13
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_static_upwards.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+double getDouble() => 0.0;
+double topLevelDouble;
+int getInt() => 0;
+int topLevelInt;
+main() {}
+num getNum() => 0;
+num topLevelNum;
+void test1() {}
+void test2() {}
+void test3() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.textual_outline.expect
new file mode 100644
index 0000000..b979107
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+abstract class A {
+ int get x;
+ void set x(double value);
+}
+
+class B extends A {
+ var x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b979107
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+abstract class A {
+ int get x;
+ void set x(double value);
+}
+
+class B extends A {
+ var x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart.textual_outline.expect
new file mode 100644
index 0000000..0edf6d2
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+abstract class A {
+ A get x;
+ void set x(B value);
+ B get y;
+ void set y(A value);
+}
+
+abstract class B extends A {}
+
+class C extends B {
+ var x;
+ var y;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4747c1a
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+abstract class A {
+ A get x;
+ B get y;
+ void set x(B value);
+ void set y(A value);
+}
+
+abstract class B extends A {}
+
+class C extends B {
+ var x;
+ var y;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.textual_outline.expect
new file mode 100644
index 0000000..305abb9
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+abstract class A {
+ void set x(num value);
+}
+
+abstract class B extends A {
+ int get x;
+}
+
+class C extends B {
+ var x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..305abb9
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+abstract class A {
+ void set x(num value);
+}
+
+abstract class B extends A {
+ int get x;
+}
+
+class C extends B {
+ var x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.textual_outline.expect
new file mode 100644
index 0000000..bd5d090
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+abstract class A {
+ num get x;
+}
+
+abstract class B extends A {
+ void set x(int value);
+}
+
+class C extends B {
+ var x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bd5d090
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+abstract class A {
+ num get x;
+}
+
+abstract class B extends A {
+ void set x(int value);
+}
+
+class C extends B {
+ var x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_instance_accessor_ref.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_instance_accessor_ref.dart.textual_outline.expect
new file mode 100644
index 0000000..2f8867c
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_instance_accessor_ref.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+library test;
+
+class A {
+ B b;
+}
+
+class B {
+ C get c => null;
+ void set c(C value) {}
+}
+
+class C {}
+
+class D extends C {}
+
+var a = new A();
+var x = a.b.c;
+var y = a.b.c ??= new D();
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_instance_accessor_ref.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_instance_accessor_ref.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4dbc562
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_instance_accessor_ref.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+library test;
+
+class A {
+ B b;
+}
+
+class B {
+ C get c => null;
+ void set c(C value) {}
+}
+
+class C {}
+
+class D extends C {}
+
+main() {}
+var a = new A();
+var x = a.b.c;
+var y = a.b.c ??= new D();
diff --git a/pkg/front_end/testcases/inference_new/infer_instance_field_ref.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_instance_field_ref.dart.textual_outline.expect
new file mode 100644
index 0000000..1c47cb0
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_instance_field_ref.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+library test;
+
+class A {
+ B b;
+}
+
+class B {
+ C c;
+}
+
+class C {}
+
+class D extends C {}
+
+var a = new A();
+var x = a.b.c;
+var y = a.b.c ??= new D();
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_instance_field_ref.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_instance_field_ref.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..83d5264
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_instance_field_ref.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+library test;
+
+class A {
+ B b;
+}
+
+class B {
+ C c;
+}
+
+class C {}
+
+class D extends C {}
+
+main() {}
+var a = new A();
+var x = a.b.c;
+var y = a.b.c ??= new D();
diff --git a/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.textual_outline.expect
new file mode 100644
index 0000000..1d3b6a2
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+class A {
+ var b = () => x;
+ var c = () => x;
+}
+
+var a = new A();
+var x = () => a.b;
+var y = () => a.c;
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9e8f476
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+class A {
+ var b = () => x;
+ var c = () => x;
+}
+
+main() {}
+var a = new A();
+var x = () => a.b;
+var y = () => a.c;
diff --git a/pkg/front_end/testcases/inference_new/infer_logical.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_logical.dart.textual_outline.expect
new file mode 100644
index 0000000..a739ce7
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_logical.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+T f<T>() => null;
+var x = f() || f();
+var y = f() && f();
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_logical.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_logical.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..15d8c5f
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_logical.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+T f<T>() => null;
+main() {}
+var x = f() || f();
+var y = f() && f();
+void test() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.textual_outline.expect
new file mode 100644
index 0000000..fccbad0
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+class B {
+ void f() {}
+}
+
+class C extends B {
+ f() {}
+}
+
+var x = new C().f();
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..deba2e5
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+class B {
+ void f() {}
+}
+
+class C extends B {
+ f() {}
+}
+
+main() {}
+var x = new C().f();
diff --git a/pkg/front_end/testcases/inference_new/invalid_assignment_during_toplevel_inference.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/invalid_assignment_during_toplevel_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..7981f61
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/invalid_assignment_during_toplevel_inference.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+int i;
+String s;
+var x = i = s;
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/invalid_assignment_during_toplevel_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/invalid_assignment_during_toplevel_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..46ffb37
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/invalid_assignment_during_toplevel_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+String s;
+int i;
+main() {}
+var x = i = s;
diff --git a/pkg/front_end/testcases/inference_new/list_literals_can_infer_null_top_level.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/list_literals_can_infer_null_top_level.dart.textual_outline.expect
new file mode 100644
index 0000000..38b2446
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/list_literals_can_infer_null_top_level.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+var x = [null];
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/list_literals_can_infer_null_top_level.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/list_literals_can_infer_null_top_level.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9294248
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/list_literals_can_infer_null_top_level.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+var x = [null];
diff --git a/pkg/front_end/testcases/inference_new/map_literals_can_infer_null_top_level.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/map_literals_can_infer_null_top_level.dart.textual_outline.expect
new file mode 100644
index 0000000..1954ad0
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/map_literals_can_infer_null_top_level.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+library test;
+
+var x = {null: null};
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/map_literals_can_infer_null_top_level.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/map_literals_can_infer_null_top_level.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..412a917
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/map_literals_can_infer_null_top_level.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+library test;
+
+main() {}
+var x = {null: null};
diff --git a/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.textual_outline.expect
new file mode 100644
index 0000000..b52257c
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.textual_outline.expect
@@ -0,0 +1,25 @@
+library test;
+
+abstract class I1 {
+ void f(int i);
+}
+
+abstract class I2 {
+ void f(Object o);
+}
+
+abstract class C implements I1, I2 {}
+
+class D extends C {
+ void f(Object o) {}
+}
+
+abstract class E implements I2, I1 {}
+
+class F extends E {
+ void f(Object o) {}
+}
+
+void g1(C c) {}
+void g2(E e) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fa895e1
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.textual_outline_modelled.expect
@@ -0,0 +1,25 @@
+library test;
+
+abstract class C implements I1, I2 {}
+
+abstract class E implements I2, I1 {}
+
+abstract class I1 {
+ void f(int i);
+}
+
+abstract class I2 {
+ void f(Object o);
+}
+
+class D extends C {
+ void f(Object o) {}
+}
+
+class F extends E {
+ void f(Object o) {}
+}
+
+main() {}
+void g1(C c) {}
+void g2(E e) {}
diff --git a/pkg/front_end/testcases/inference_new/null_aware_property_get.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/null_aware_property_get.dart.textual_outline.expect
new file mode 100644
index 0000000..f19d7b2
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/null_aware_property_get.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class Class {
+ T method<T>() => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/null_aware_property_get.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/null_aware_property_get.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f19d7b2
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/null_aware_property_get.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class Class {
+ T method<T>() => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/property_assign_combiner.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/property_assign_combiner.dart.textual_outline.expect
new file mode 100644
index 0000000..530257a
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/property_assign_combiner.dart.textual_outline.expect
@@ -0,0 +1,31 @@
+library test;
+
+T f<T>() => null;
+
+class A {
+ C operator +(int value) => null;
+ C operator *(D value) => null;
+}
+
+class B {
+ E operator +(int value) => null;
+ E operator *(F value) => null;
+}
+
+class C extends B {}
+
+class D {}
+
+class E {}
+
+class F {}
+
+class G {
+ A get target => null;
+ void set target(B value) {}
+}
+
+void test1(G g) {}
+void test2(G g) {}
+void test3(G g) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/property_assign_combiner.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/property_assign_combiner.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fdf8b09
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/property_assign_combiner.dart.textual_outline_modelled.expect
@@ -0,0 +1,31 @@
+library test;
+
+T f<T>() => null;
+
+class A {
+ C operator *(D value) => null;
+ C operator +(int value) => null;
+}
+
+class B {
+ E operator *(F value) => null;
+ E operator +(int value) => null;
+}
+
+class C extends B {}
+
+class D {}
+
+class E {}
+
+class F {}
+
+class G {
+ A get target => null;
+ void set target(B value) {}
+}
+
+main() {}
+void test1(G g) {}
+void test2(G g) {}
+void test3(G g) {}
diff --git a/pkg/front_end/testcases/inference_new/property_get_toplevel.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/property_get_toplevel.dart.textual_outline.expect
new file mode 100644
index 0000000..efab0ad
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/property_get_toplevel.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+library test;
+
+class C {
+ int field = 0;
+ int get getter => 0;
+ int function() => 0;
+}
+
+C c = new C();
+var field_ref = c.field;
+var getter_ref = c.getter;
+var function_ref = c.function;
+var field_ref_list = [c.field];
+var getter_ref_list = [c.getter];
+var function_ref_list = [c.function];
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/property_get_toplevel.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/property_get_toplevel.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4e1e6c5
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/property_get_toplevel.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+library test;
+
+C c = new C();
+
+class C {
+ int field = 0;
+ int function() => 0;
+ int get getter => 0;
+}
+
+main() {}
+var field_ref = c.field;
+var field_ref_list = [c.field];
+var function_ref = c.function;
+var function_ref_list = [c.function];
+var getter_ref = c.getter;
+var getter_ref_list = [c.getter];
diff --git a/pkg/front_end/testcases/inference_new/static_assign_combiner.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/static_assign_combiner.dart.textual_outline.expect
new file mode 100644
index 0000000..f23864b
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/static_assign_combiner.dart.textual_outline.expect
@@ -0,0 +1,28 @@
+library test;
+
+T f<T>() => null;
+
+class A {
+ C operator +(int value) => null;
+ C operator *(D value) => null;
+}
+
+class B {
+ E operator +(int value) => null;
+ E operator *(F value) => null;
+}
+
+class C extends B {}
+
+class D {}
+
+class E {}
+
+class F {}
+
+A get target => null;
+void set target(B value) {}
+void test1() {}
+void test2() {}
+void test3() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/static_assign_combiner.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/static_assign_combiner.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1fbf16f
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/static_assign_combiner.dart.textual_outline_modelled.expect
@@ -0,0 +1,28 @@
+library test;
+
+A get target => null;
+T f<T>() => null;
+
+class A {
+ C operator *(D value) => null;
+ C operator +(int value) => null;
+}
+
+class B {
+ E operator *(F value) => null;
+ E operator +(int value) => null;
+}
+
+class C extends B {}
+
+class D {}
+
+class E {}
+
+class F {}
+
+main() {}
+void set target(B value) {}
+void test1() {}
+void test2() {}
+void test3() {}
diff --git a/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.textual_outline.expect
new file mode 100644
index 0000000..d4c04a6
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+bool f() => null;
+var x = () => f() ? y : z;
+var y = () => x;
+var z = () => x;
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..667ba69
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+bool f() => null;
+main() {}
+var x = () => f() ? y : z;
+var y = () => x;
+var z = () => x;
diff --git a/pkg/front_end/testcases/inference_new/super_index_get.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/super_index_get.dart.textual_outline.expect
new file mode 100644
index 0000000..17a5a7c
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/super_index_get.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+library test;
+
+import 'dart:async';
+
+T f<T>() => null;
+
+class B {
+ num operator [](int x) => null;
+}
+
+class C extends B {
+ int operator [](Object x) => null;
+ void h() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/super_index_get.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/super_index_get.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..17a5a7c
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/super_index_get.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+library test;
+
+import 'dart:async';
+
+T f<T>() => null;
+
+class B {
+ num operator [](int x) => null;
+}
+
+class C extends B {
+ int operator [](Object x) => null;
+ void h() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.textual_outline.expect
new file mode 100644
index 0000000..9fe3d8e
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.textual_outline.expect
@@ -0,0 +1,20 @@
+library test;
+
+import 'dart:async';
+
+T f<T>() => null;
+
+class D<T> {}
+
+class E<T> extends D<T> {}
+
+class B<T> {
+ D<T> operator [](E<T> x) => null;
+}
+
+class C<U> extends B<Future<U>> {
+ E<Future<U>> operator [](Object x) => null;
+ void h() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d7d40b7
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.textual_outline_modelled.expect
@@ -0,0 +1,20 @@
+library test;
+
+import 'dart:async';
+
+T f<T>() => null;
+
+class B<T> {
+ D<T> operator [](E<T> x) => null;
+}
+
+class C<U> extends B<Future<U>> {
+ E<Future<U>> operator [](Object x) => null;
+ void h() {}
+}
+
+class D<T> {}
+
+class E<T> extends D<T> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/switch.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/switch.dart.textual_outline.expect
new file mode 100644
index 0000000..05de058
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/switch.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+T f<T>() => null;
+
+class C<T> {
+ const C();
+}
+
+void test(C<int> x) {}
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/switch.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/switch.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9107352
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/switch.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+T f<T>() => null;
+
+class C<T> {
+ const C();
+}
+
+main() {}
+void test(C<int> x) {}
diff --git a/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.textual_outline.expect
new file mode 100644
index 0000000..7486465
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.textual_outline.expect
@@ -0,0 +1,29 @@
+library test;
+
+class A {}
+
+class B extends A {}
+
+class C extends B {}
+
+abstract class D {
+ A foo();
+}
+
+abstract class E {
+ B foo();
+}
+
+abstract class F {
+ Object foo();
+}
+
+abstract class G extends Object implements D, E, F {}
+
+class H extends G {
+ C foo() => new C();
+}
+
+G bar() => new H();
+var x = bar().foo();
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..16dd2e3e
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.textual_outline_modelled.expect
@@ -0,0 +1,30 @@
+library test;
+
+G bar() => new H();
+
+abstract class D {
+ A foo();
+}
+
+abstract class E {
+ B foo();
+}
+
+abstract class F {
+ Object foo();
+}
+
+abstract class G extends Object implements D, E, F {}
+
+class A {}
+
+class B extends A {}
+
+class C extends B {}
+
+class H extends G {
+ C foo() => new C();
+}
+
+main() {}
+var x = bar().foo();
diff --git a/pkg/front_end/testcases/inference_new/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr2.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr2.dart.textual_outline.expect
new file mode 100644
index 0000000..7e89a23
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr2.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+List<T> f<T>(T g()) => <T>[g()];
+var v = (f)(() {
+ return 1;
+});
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f4b01cf
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr2.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+List<T> f<T>(T g()) => <T>[g()];
+main() {}
+var v = (f)(() {
+ return 1;
+});
diff --git a/pkg/front_end/testcases/inference_new/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr2.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr2.dart.textual_outline.expect
new file mode 100644
index 0000000..7e89a23
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr2.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+List<T> f<T>(T g()) => <T>[g()];
+var v = (f)(() {
+ return 1;
+});
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f4b01cf
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr2.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+List<T> f<T>(T g()) => <T>[g()];
+main() {}
+var v = (f)(() {
+ return 1;
+});
diff --git a/pkg/front_end/testcases/inference_new/void_return_type_subtypes_dynamic.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/void_return_type_subtypes_dynamic.dart.textual_outline.expect
new file mode 100644
index 0000000..2536526
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/void_return_type_subtypes_dynamic.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+library test;
+
+T run<T>(T f()) {}
+void printRunning() {}
+var y = run(printRunning);
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/void_return_type_subtypes_dynamic.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/void_return_type_subtypes_dynamic.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1e8174f
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/void_return_type_subtypes_dynamic.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+library test;
+
+T run<T>(T f()) {}
+main() {}
+var y = run(printRunning);
+void printRunning() {}
diff --git a/pkg/front_end/testcases/inference_new/while_loop.dart.textual_outline.expect b/pkg/front_end/testcases/inference_new/while_loop.dart.textual_outline.expect
new file mode 100644
index 0000000..cdb201d
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/while_loop.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+library test;
+
+T f<T>() => null;
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/while_loop.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/inference_new/while_loop.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b66d908
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/while_loop.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+library test;
+
+T f<T>() => null;
+main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/all_steps.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/all_steps.dart.textual_outline.expect
new file mode 100644
index 0000000..a476c9a
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/all_steps.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+class B<X, Y> {}
+
+class C<X, Y> {}
+
+class D<X extends B<X, Y>, Y extends C<X, Y>, Z extends X Function(Y),
+ W extends num> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/all_steps.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/all_steps.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a476c9a
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/all_steps.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+class B<X, Y> {}
+
+class C<X, Y> {}
+
+class D<X extends B<X, Y>, Y extends C<X, Y>, Z extends X Function(Y),
+ W extends num> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_generic_classes_from_dill.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/body_generic_classes_from_dill.dart.textual_outline.expect
new file mode 100644
index 0000000..1f89431
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_generic_classes_from_dill.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+import 'dart:collection';
+
+class A {
+ foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_generic_classes_from_dill.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/body_generic_classes_from_dill.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1f89431
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_generic_classes_from_dill.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+import 'dart:collection';
+
+class A {
+ foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_literal_list.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/body_literal_list.dart.textual_outline.expect
new file mode 100644
index 0000000..c610622
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_literal_list.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class A<T extends num> {}
+
+class B {
+ foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_literal_list.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/body_literal_list.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c610622
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_literal_list.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class A<T extends num> {}
+
+class B {
+ foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_literal_list_with_generic_argument.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/body_literal_list_with_generic_argument.dart.textual_outline.expect
new file mode 100644
index 0000000..276f316
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_literal_list_with_generic_argument.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class A<T> {}
+
+class B<U> {
+ fun() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_literal_list_with_generic_argument.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/body_literal_list_with_generic_argument.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..276f316
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_literal_list_with_generic_argument.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class A<T> {}
+
+class B<U> {
+ fun() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_literal_map.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/body_literal_map.dart.textual_outline.expect
new file mode 100644
index 0000000..c610622
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_literal_map.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class A<T extends num> {}
+
+class B {
+ foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_literal_map.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/body_literal_map.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c610622
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_literal_map.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class A<T extends num> {}
+
+class B {
+ foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_omitted_bound.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/body_omitted_bound.dart.textual_outline.expect
new file mode 100644
index 0000000..ed3c7fe
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_omitted_bound.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+import 'dart:collection';
+
+class A<T> {}
+
+class C {
+ fun() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_omitted_bound.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/body_omitted_bound.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ed3c7fe
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_omitted_bound.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+import 'dart:collection';
+
+class A<T> {}
+
+class C {
+ fun() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_super_bounded_type.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/body_super_bounded_type.dart.textual_outline.expect
new file mode 100644
index 0000000..2b6461d
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_super_bounded_type.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class A<T extends A<T>> {}
+
+class B {
+ foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_super_bounded_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/body_super_bounded_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2b6461d
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_super_bounded_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class A<T extends A<T>> {}
+
+class B {
+ foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list.dart.textual_outline.expect
new file mode 100644
index 0000000..bc2eead
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+typedef A<T extends num>(T p);
+
+class B {
+ foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..30c7151
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class B {
+ foo() {}
+}
+
+main() {}
+typedef A<T extends num>(T p);
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list_with_generic_argument.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list_with_generic_argument.dart.textual_outline.expect
new file mode 100644
index 0000000..edfd3bd
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list_with_generic_argument.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+typedef A<T>(T p);
+
+class B<U> {
+ fun() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list_with_generic_argument.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list_with_generic_argument.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c142ab4
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list_with_generic_argument.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class B<U> {
+ fun() {}
+}
+
+main() {}
+typedef A<T>(T p);
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_map.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_map.dart.textual_outline.expect
new file mode 100644
index 0000000..bc2eead
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_map.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+typedef A<T extends num>(T p);
+
+class B {
+ foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_map.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_map.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..30c7151
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_map.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class B {
+ foo() {}
+}
+
+main() {}
+typedef A<T extends num>(T p);
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_omitted_bound.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_omitted_bound.dart.textual_outline.expect
new file mode 100644
index 0000000..a5935b8
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_omitted_bound.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+typedef A<T>(T p);
+
+class C {
+ foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_omitted_bound.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_omitted_bound.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9881ae4
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_omitted_bound.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class C {
+ foo() {}
+}
+
+main() {}
+typedef A<T>(T p);
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_super_bounded_type.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_super_bounded_type.dart.textual_outline.expect
new file mode 100644
index 0000000..0fdd67a
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_super_bounded_type.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+typedef A<T>(T p);
+typedef B<U extends A<U>>(U p);
+
+class C {
+ foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_super_bounded_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_super_bounded_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e05e4bd
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_super_bounded_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class C {
+ foo() {}
+}
+
+main() {}
+typedef A<T>(T p);
+typedef B<U extends A<U>>(U p);
diff --git a/pkg/front_end/testcases/instantiate_to_bound/contravariant_dependence.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/contravariant_dependence.dart.textual_outline.expect
new file mode 100644
index 0000000..fcc1eeb
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/contravariant_dependence.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class C<X extends num, Y extends void Function(X)> {}
+
+C c;
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/contravariant_dependence.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/contravariant_dependence.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e511f6a
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/contravariant_dependence.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+C c;
+
+class C<X extends num, Y extends void Function(X)> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/contravariant_dependence_in_literals.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/contravariant_dependence_in_literals.dart.textual_outline.expect
new file mode 100644
index 0000000..e4cafc7
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/contravariant_dependence_in_literals.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class C<X extends num, Y extends void Function(X)> {}
+
+var lc = <C>[];
+var mc = <C, C>{};
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/contravariant_dependence_in_literals.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/contravariant_dependence_in_literals.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1572ad5
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/contravariant_dependence_in_literals.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+class C<X extends num, Y extends void Function(X)> {}
+
+main() {}
+var lc = <C>[];
+var mc = <C, C>{};
diff --git a/pkg/front_end/testcases/instantiate_to_bound/contravariant_mutual_dependence.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/contravariant_mutual_dependence.dart.textual_outline.expect
new file mode 100644
index 0000000..4365e51
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/contravariant_mutual_dependence.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+class D<X extends void Function(X, Y), Y extends void Function(X, Y)> {}
+
+D d;
+
+class E<X extends void Function(X)> {}
+
+E e;
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/contravariant_mutual_dependence.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/contravariant_mutual_dependence.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..18b63b4
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/contravariant_mutual_dependence.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+D d;
+E e;
+
+class D<X extends void Function(X, Y), Y extends void Function(X, Y)> {}
+
+class E<X extends void Function(X)> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/contravariant_mutual_dependence_in_literals.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/contravariant_mutual_dependence_in_literals.dart.textual_outline.expect
new file mode 100644
index 0000000..0e699bf
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/contravariant_mutual_dependence_in_literals.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class D<X extends void Function(X, Y), Y extends void Function(X, Y)> {}
+
+var ld = <D>[];
+var md = <D, D>{};
+
+class E<X extends void Function(X)> {}
+
+var le = <E>[];
+var me = <E, E>{};
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/contravariant_mutual_dependence_in_literals.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/contravariant_mutual_dependence_in_literals.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c05a14c
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/contravariant_mutual_dependence_in_literals.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class D<X extends void Function(X, Y), Y extends void Function(X, Y)> {}
+
+class E<X extends void Function(X)> {}
+
+main() {}
+var ld = <D>[];
+var le = <E>[];
+var md = <D, D>{};
+var me = <E, E>{};
diff --git a/pkg/front_end/testcases/instantiate_to_bound/covariant_dependence.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/covariant_dependence.dart.textual_outline.expect
new file mode 100644
index 0000000..4144570
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/covariant_dependence.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+class A<X> {}
+
+class C<X, Y extends A<X>> {}
+
+C c;
+
+class D<X extends num, Y extends A<X>> {}
+
+D d;
+
+class E<X, Y extends X Function()> {}
+
+E e;
+
+class F<X extends num, Y extends X Function()> {}
+
+F f;
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/covariant_dependence.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/covariant_dependence.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e6df593
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/covariant_dependence.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+C c;
+D d;
+E e;
+F f;
+
+class A<X> {}
+
+class C<X, Y extends A<X>> {}
+
+class D<X extends num, Y extends A<X>> {}
+
+class E<X, Y extends X Function()> {}
+
+class F<X extends num, Y extends X Function()> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/covariant_dependence_in_literals.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/covariant_dependence_in_literals.dart.textual_outline.expect
new file mode 100644
index 0000000..498ba79
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/covariant_dependence_in_literals.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+class A<X> {}
+
+class C<X, Y extends A<X>> {}
+
+var lc = <C>[];
+var mc = <C, C>{};
+
+class D<X extends num, Y extends A<X>> {}
+
+var ld = <D>[];
+var md = <D, D>{};
+
+class E<X, Y extends X Function()> {}
+
+var le = <E>[];
+var me = <E, E>{};
+
+class F<X extends num, Y extends X Function()> {}
+
+var lf = <F>[];
+var mf = <F, F>{};
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/covariant_dependence_in_literals.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/covariant_dependence_in_literals.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5ae4099
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/covariant_dependence_in_literals.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+class A<X> {}
+
+class C<X, Y extends A<X>> {}
+
+class D<X extends num, Y extends A<X>> {}
+
+class E<X, Y extends X Function()> {}
+
+class F<X extends num, Y extends X Function()> {}
+
+main() {}
+var lc = <C>[];
+var ld = <D>[];
+var le = <E>[];
+var lf = <F>[];
+var mc = <C, C>{};
+var md = <D, D>{};
+var me = <E, E>{};
+var mf = <F, F>{};
diff --git a/pkg/front_end/testcases/instantiate_to_bound/covariant_mutual_dependence.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/covariant_mutual_dependence.dart.textual_outline.expect
new file mode 100644
index 0000000..03f7e21
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/covariant_mutual_dependence.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+class B<X, Y> {}
+
+class C<X, Y> {}
+
+class D<X extends B<X, Y>, Y extends C<X, Y>> {}
+
+D d;
+
+class E<X extends B<X, Y>, Y extends X Function()> {}
+
+E e;
+
+class F<X extends X Function()> {}
+
+F f;
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/covariant_mutual_dependence.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/covariant_mutual_dependence.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6c2e53b
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/covariant_mutual_dependence.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+D d;
+E e;
+F f;
+
+class B<X, Y> {}
+
+class C<X, Y> {}
+
+class D<X extends B<X, Y>, Y extends C<X, Y>> {}
+
+class E<X extends B<X, Y>, Y extends X Function()> {}
+
+class F<X extends X Function()> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/covariant_mutual_dependence_in_literals.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/covariant_mutual_dependence_in_literals.dart.textual_outline.expect
new file mode 100644
index 0000000..bd6e734
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/covariant_mutual_dependence_in_literals.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+class B<X, Y> {}
+
+class C<X, Y> {}
+
+class D<X extends B<X, Y>, Y extends C<X, Y>> {}
+
+var ld = <D>[];
+var md = <D, D>{};
+
+class E<X extends B<X, Y>, Y extends X Function()> {}
+
+var le = <E>[];
+var me = <E, E>{};
+
+class F<X extends X Function()> {}
+
+var lf = <F>[];
+var mf = <F, F>{};
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/covariant_mutual_dependence_in_literals.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/covariant_mutual_dependence_in_literals.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..eb9c16e
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/covariant_mutual_dependence_in_literals.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+class B<X, Y> {}
+
+class C<X, Y> {}
+
+class D<X extends B<X, Y>, Y extends C<X, Y>> {}
+
+class E<X extends B<X, Y>, Y extends X Function()> {}
+
+class F<X extends X Function()> {}
+
+main() {}
+var ld = <D>[];
+var le = <E>[];
+var lf = <F>[];
+var md = <D, D>{};
+var me = <E, E>{};
+var mf = <F, F>{};
diff --git a/pkg/front_end/testcases/instantiate_to_bound/dependence.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/dependence.dart.textual_outline.expect
new file mode 100644
index 0000000..6d25aa6
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/dependence.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class A<X> {}
+
+class C<X, Y extends X Function(X)> {}
+
+C c;
+
+class D<X extends num, Y extends X Function(X)> {}
+
+D d;
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/dependence.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/dependence.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..90db448
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/dependence.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+C c;
+D d;
+
+class A<X> {}
+
+class C<X, Y extends X Function(X)> {}
+
+class D<X extends num, Y extends X Function(X)> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/dependence_in_literals.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/dependence_in_literals.dart.textual_outline.expect
new file mode 100644
index 0000000..fc6b50f
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/dependence_in_literals.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+class A<X> {}
+
+class C<X, Y extends X Function(X)> {}
+
+var lc = <C>[];
+var mc = <C, C>{};
+
+class D<X extends num, Y extends X Function(X)> {}
+
+var ld = <D>[];
+var md = <D, D>{};
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/dependence_in_literals.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/dependence_in_literals.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..dd05869
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/dependence_in_literals.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+class A<X> {}
+
+class C<X, Y extends X Function(X)> {}
+
+class D<X extends num, Y extends X Function(X)> {}
+
+main() {}
+var lc = <C>[];
+var ld = <D>[];
+var mc = <C, C>{};
+var md = <D, D>{};
diff --git a/pkg/front_end/testcases/instantiate_to_bound/generic_classes_from_dill.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/generic_classes_from_dill.dart.textual_outline.expect
new file mode 100644
index 0000000..f49c29b
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/generic_classes_from_dill.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'dart:collection';
+
+LinkedListEntry y;
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/generic_classes_from_dill.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/generic_classes_from_dill.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f49c29b
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/generic_classes_from_dill.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'dart:collection';
+
+LinkedListEntry y;
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/inference_constrained_by_bound.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/inference_constrained_by_bound.dart.textual_outline.expect
new file mode 100644
index 0000000..e078af5
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/inference_constrained_by_bound.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+class A<T extends num> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/inference_constrained_by_bound.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/inference_constrained_by_bound.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e078af5
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/inference_constrained_by_bound.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+class A<T extends num> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/inference_defaults_to_bound.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/inference_defaults_to_bound.dart.textual_outline.expect
new file mode 100644
index 0000000..e078af5
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/inference_defaults_to_bound.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+class A<T extends num> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/inference_defaults_to_bound.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/inference_defaults_to_bound.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e078af5
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/inference_defaults_to_bound.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+class A<T extends num> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/inference_gives_input.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/inference_gives_input.dart.textual_outline.expect
new file mode 100644
index 0000000..d7289c3
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/inference_gives_input.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class A<T> {}
+
+class B<T extends num, S extends List<T>> extends A<T> {
+ B([T x]) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/inference_gives_input.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/inference_gives_input.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d7289c3
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/inference_gives_input.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class A<T> {}
+
+class B<T extends num, S extends List<T>> extends A<T> {
+ B([T x]) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart.textual_outline.expect
new file mode 100644
index 0000000..d9993ef
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class B<T extends Comparable<T>> {}
+
+var y = new B();
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..58bc104
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+class B<T extends Comparable<T>> {}
+
+main() {}
+var y = new B();
diff --git a/pkg/front_end/testcases/instantiate_to_bound/instantiated_in_outline.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/instantiated_in_outline.dart.textual_outline.expect
new file mode 100644
index 0000000..e4c532d
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/instantiated_in_outline.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+class A<T extends num> {}
+
+class B {
+ foo(A a) => null;
+ A bar() => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/instantiated_in_outline.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/instantiated_in_outline.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0e5c7b8
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/instantiated_in_outline.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+class A<T extends num> {}
+
+class B {
+ A bar() => null;
+ foo(A a) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/literal_list.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/literal_list.dart.textual_outline.expect
new file mode 100644
index 0000000..2e3bf3c
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/literal_list.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class A<T extends num> {}
+
+var a = <A>[];
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/literal_list.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/literal_list.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9b30539
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/literal_list.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+class A<T extends num> {}
+
+main() {}
+var a = <A>[];
diff --git a/pkg/front_end/testcases/instantiate_to_bound/literal_list_with_generic_argument.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/literal_list_with_generic_argument.dart.textual_outline.expect
new file mode 100644
index 0000000..fcb0347
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/literal_list_with_generic_argument.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+class A<T> {}
+
+class B<S> {
+ final List<A<S>> foo = <A<S>>[];
+ final List<A<num>> bar = <A<num>>[];
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/literal_list_with_generic_argument.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/literal_list_with_generic_argument.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fcb0347
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/literal_list_with_generic_argument.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+class A<T> {}
+
+class B<S> {
+ final List<A<S>> foo = <A<S>>[];
+ final List<A<num>> bar = <A<num>>[];
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/literal_map.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/literal_map.dart.textual_outline.expect
new file mode 100644
index 0000000..3f4f92e
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/literal_map.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class A<T extends num> {}
+
+var a = <A, A>{};
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/literal_map.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/literal_map.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f4ec5d2
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/literal_map.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+class A<T extends num> {}
+
+main() {}
+var a = <A, A>{};
diff --git a/pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart.textual_outline.expect
new file mode 100644
index 0000000..d99aa50
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart.textual_outline.expect
@@ -0,0 +1,47 @@
+class A<X> {}
+
+class B<X, Y> {}
+
+class C<X, Y> {}
+
+class D<X extends A<X>, Y extends A<Y>> {}
+
+D d;
+
+class E<W extends B<W, X>, X extends C<W, X>, Y extends B<Y, Z>,
+ Z extends C<Y, Z>> {}
+
+E e;
+
+class F<V extends num, W extends B<W, X>, X extends C<W, X>, Y extends B<W, X>,
+ Z extends C<Y, Z>> {}
+
+F f;
+
+class G<V extends num, W extends B<V, X>, X extends C<W, V>, Y extends B<W, X>,
+ Z extends C<Y, Z>> {}
+
+G g;
+
+class H<S extends A<S>, T extends B<T, U>, U extends C<T, U>, V extends A<V>,
+ W extends S, X extends T, Y extends U, Z extends V> {}
+
+H h;
+
+class I<T extends U, U extends Y, V extends Function(W), W extends Function(X),
+ X extends Function(V), Y extends Z, Z extends T> {}
+
+I i;
+
+class J<
+ S extends T Function(U),
+ T extends U Function(S),
+ U extends S Function(T),
+ V extends W,
+ W extends X,
+ X extends Y Function(V),
+ Y extends Z,
+ Z extends X> {}
+
+J j;
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ecd3e9f
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart.textual_outline_modelled.expect
@@ -0,0 +1,42 @@
+D d;
+E e;
+F f;
+G g;
+H h;
+I i;
+J j;
+
+class A<X> {}
+
+class B<X, Y> {}
+
+class C<X, Y> {}
+
+class D<X extends A<X>, Y extends A<Y>> {}
+
+class E<W extends B<W, X>, X extends C<W, X>, Y extends B<Y, Z>,
+ Z extends C<Y, Z>> {}
+
+class F<V extends num, W extends B<W, X>, X extends C<W, X>, Y extends B<W, X>,
+ Z extends C<Y, Z>> {}
+
+class G<V extends num, W extends B<V, X>, X extends C<W, V>, Y extends B<W, X>,
+ Z extends C<Y, Z>> {}
+
+class H<S extends A<S>, T extends B<T, U>, U extends C<T, U>, V extends A<V>,
+ W extends S, X extends T, Y extends U, Z extends V> {}
+
+class I<T extends U, U extends Y, V extends Function(W), W extends Function(X),
+ X extends Function(V), Y extends Z, Z extends T> {}
+
+class J<
+ S extends T Function(U),
+ T extends U Function(S),
+ U extends S Function(T),
+ V extends W,
+ W extends X,
+ X extends Y Function(V),
+ Y extends Z,
+ Z extends X> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/mutual_dependence.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/mutual_dependence.dart.textual_outline.expect
new file mode 100644
index 0000000..78b4c2d
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/mutual_dependence.dart.textual_outline.expect
@@ -0,0 +1,38 @@
+class B<X, Y> {}
+
+class C1<X extends X Function(Y), Y extends X Function(Y)> {}
+
+C1 c1;
+
+class C2<X extends X Function(Y), Y extends Y Function(X)> {}
+
+C2 c2;
+
+class C3<X extends X Function(X, Y), Y extends X Function(X, Y)> {}
+
+C3 c3;
+
+class C4<X extends X Function(X, Y), Y extends Y Function(X, Y)> {}
+
+C4 c4;
+
+class D1<X extends B<X, Y>, Y extends X Function(Y)> {}
+
+D1 d1;
+
+class D2<X extends B<X, Y>, Y extends Y Function(X)> {}
+
+D2 d2;
+
+class D3<X extends B<X, Y>, Y extends X Function(X, Y)> {}
+
+D3 d3;
+
+class D4<X extends B<X, Y>, Y extends Y Function(X, Y)> {}
+
+D4 d4;
+
+class E<X extends X Function(X)> {}
+
+E e;
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/mutual_dependence.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/mutual_dependence.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e9b691b
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/mutual_dependence.dart.textual_outline_modelled.expect
@@ -0,0 +1,31 @@
+C1 c1;
+C2 c2;
+C3 c3;
+C4 c4;
+D1 d1;
+D2 d2;
+D3 d3;
+D4 d4;
+E e;
+
+class B<X, Y> {}
+
+class C1<X extends X Function(Y), Y extends X Function(Y)> {}
+
+class C2<X extends X Function(Y), Y extends Y Function(X)> {}
+
+class C3<X extends X Function(X, Y), Y extends X Function(X, Y)> {}
+
+class C4<X extends X Function(X, Y), Y extends Y Function(X, Y)> {}
+
+class D1<X extends B<X, Y>, Y extends X Function(Y)> {}
+
+class D2<X extends B<X, Y>, Y extends Y Function(X)> {}
+
+class D3<X extends B<X, Y>, Y extends X Function(X, Y)> {}
+
+class D4<X extends B<X, Y>, Y extends Y Function(X, Y)> {}
+
+class E<X extends X Function(X)> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/mutual_dependence_in_literals.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/mutual_dependence_in_literals.dart.textual_outline.expect
new file mode 100644
index 0000000..4c6bc43
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/mutual_dependence_in_literals.dart.textual_outline.expect
@@ -0,0 +1,47 @@
+class B<X, Y> {}
+
+class C1<X extends X Function(Y), Y extends X Function(Y)> {}
+
+var lc1 = <C1>[];
+var mc1 = <C1, C1>{};
+
+class C2<X extends X Function(Y), Y extends Y Function(X)> {}
+
+var lc2 = <C2>[];
+var mc2 = <C2, C2>{};
+
+class C3<X extends X Function(X, Y), Y extends X Function(X, Y)> {}
+
+var lc3 = <C3>[];
+var mc3 = <C3, C3>{};
+
+class C4<X extends X Function(X, Y), Y extends Y Function(X, Y)> {}
+
+var lc4 = <C4>[];
+var mc4 = <C4, C4>{};
+
+class D1<X extends B<X, Y>, Y extends X Function(Y)> {}
+
+var ld1 = <D1>[];
+var md1 = <D1, D1>{};
+
+class D2<X extends B<X, Y>, Y extends Y Function(X)> {}
+
+var ld2 = <D2>[];
+var md2 = <D2, D2>{};
+
+class D3<X extends B<X, Y>, Y extends X Function(X, Y)> {}
+
+var ld3 = <D3>[];
+var md3 = <D3, D3>{};
+
+class D4<X extends B<X, Y>, Y extends Y Function(X, Y)> {}
+
+var ld4 = <D4>[];
+var md4 = <D4, D4>{};
+
+class E<X extends X Function(X)> {}
+
+var le = <E>[];
+var me = <E, E>{};
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/mutual_dependence_in_literals.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/mutual_dependence_in_literals.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..df9101b
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/mutual_dependence_in_literals.dart.textual_outline_modelled.expect
@@ -0,0 +1,39 @@
+class B<X, Y> {}
+
+class C1<X extends X Function(Y), Y extends X Function(Y)> {}
+
+class C2<X extends X Function(Y), Y extends Y Function(X)> {}
+
+class C3<X extends X Function(X, Y), Y extends X Function(X, Y)> {}
+
+class C4<X extends X Function(X, Y), Y extends Y Function(X, Y)> {}
+
+class D1<X extends B<X, Y>, Y extends X Function(Y)> {}
+
+class D2<X extends B<X, Y>, Y extends Y Function(X)> {}
+
+class D3<X extends B<X, Y>, Y extends X Function(X, Y)> {}
+
+class D4<X extends B<X, Y>, Y extends Y Function(X, Y)> {}
+
+class E<X extends X Function(X)> {}
+
+main() {}
+var lc1 = <C1>[];
+var lc2 = <C2>[];
+var lc3 = <C3>[];
+var lc4 = <C4>[];
+var ld1 = <D1>[];
+var ld2 = <D2>[];
+var ld3 = <D3>[];
+var ld4 = <D4>[];
+var le = <E>[];
+var mc1 = <C1, C1>{};
+var mc2 = <C2, C2>{};
+var mc3 = <C3, C3>{};
+var mc4 = <C4, C4>{};
+var md1 = <D1, D1>{};
+var md2 = <D2, D2>{};
+var md3 = <D3, D3>{};
+var md4 = <D4, D4>{};
+var me = <E, E>{};
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_non_simple.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_non_simple.dart.textual_outline.expect
new file mode 100644
index 0000000..4c7df9e
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_non_simple.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+class A<TypeT, TypeS extends TypeT> {}
+
+class B<TypeU extends A> {}
+
+class C<TypeV extends B> {}
+
+C c;
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_non_simple.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_non_simple.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fabfa1a
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_non_simple.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+C c;
+
+class A<TypeT, TypeS extends TypeT> {}
+
+class B<TypeU extends A> {}
+
+class C<TypeV extends B> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_variables.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_variables.dart.textual_outline.expect
new file mode 100644
index 0000000..4b40c441
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_variables.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class A<TypeT, TypeS extends TypeT> {}
+
+class B<TypeU extends A> {}
+
+B b;
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_variables.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_variables.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1d7b57f
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_variables.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+B b;
+
+class A<TypeT, TypeS extends TypeT> {}
+
+class B<TypeU extends A> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle.dart.textual_outline.expect
new file mode 100644
index 0000000..e977e49
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class Hest<TypeX extends Fisk> {}
+
+typedef Fisk = void Function<TypeY extends Hest>();
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7213ffd
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+class Hest<TypeX extends Fisk> {}
+
+main() {}
+typedef Fisk = void Function<TypeY extends Hest>();
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart.textual_outline.expect
new file mode 100644
index 0000000..f524d0c
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class Hest<TypeX extends Fisk> {}
+
+typedef void Fisk<TypeY extends Hest>();
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b7b4f11
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+class Hest<TypeX extends Fisk> {}
+
+main() {}
+typedef void Fisk<TypeY extends Hest>();
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive.dart.textual_outline.expect
new file mode 100644
index 0000000..bd9ba50
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+class Hest<TypeX extends Hest> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bd9ba50
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+class Hest<TypeX extends Hest> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_for_each.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_for_each.dart.textual_outline.expect
new file mode 100644
index 0000000..ff0266b2
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_for_each.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+class Hest<TypeX extends Hest, TypeY extends Hest> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_for_each.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_for_each.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ff0266b2
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_for_each.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+class Hest<TypeX extends Hest, TypeY extends Hest> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_no_dup.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_no_dup.dart.textual_outline.expect
new file mode 100644
index 0000000..c2a3766
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_no_dup.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+class Hest<TypeX extends Map<Hest, Hest>> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_no_dup.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_no_dup.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c2a3766
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_no_dup.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+class Hest<TypeX extends Map<Hest, Hest>> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_folded_regress.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_folded_regress.dart.textual_outline.expect
new file mode 100644
index 0000000..d637216
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_folded_regress.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class Hest<TypeX> {}
+
+class Fisk<TypeY extends Hest<Hest<Object>>> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_folded_regress.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_folded_regress.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e5df9718
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_folded_regress.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+class Fisk<TypeY extends Hest<Hest<Object>>> {}
+
+class Hest<TypeX> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_for_each.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_for_each.dart.textual_outline.expect
new file mode 100644
index 0000000..dec8c30
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_for_each.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class Hest<TypeX extends Hest<TypeX>> {}
+
+class Fisk<TypeY extends Hest, TypeZ extends Hest> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_for_each.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_for_each.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e8fe427
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_for_each.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+class Fisk<TypeY extends Hest, TypeZ extends Hest> {}
+
+class Hest<TypeX extends Hest<TypeX>> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.textual_outline.expect
new file mode 100644
index 0000000..ae4efd5
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'dart:collection';
+
+class Hest<X extends LinkedListEntry> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ae4efd5
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import 'dart:collection';
+
+class Hest<X extends LinkedListEntry> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_generic_function_in_bound_regress.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_generic_function_in_bound_regress.dart.textual_outline.expect
new file mode 100644
index 0000000..16b2fd1
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_generic_function_in_bound_regress.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class Hest<TypeX extends Hest<TypeX>> {}
+
+class Fisk<TypeY extends Function<TypeZ extends Hest<Null>>(TypeZ)> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_generic_function_in_bound_regress.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_generic_function_in_bound_regress.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d4c532a
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_generic_function_in_bound_regress.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+class Fisk<TypeY extends Function<TypeZ extends Hest<Null>>(TypeZ)> {}
+
+class Hest<TypeX extends Hest<TypeX>> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many.dart.textual_outline.expect
new file mode 100644
index 0000000..2138431
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class Hest<TypeX extends Hest<TypeX>> {}
+
+class Fisk<TypeY extends Fisk<TypeY>> {}
+
+class Naebdyr<TypeZ extends Map<Hest, Fisk>> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c60a816
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class Fisk<TypeY extends Fisk<TypeY>> {}
+
+class Hest<TypeX extends Hest<TypeX>> {}
+
+class Naebdyr<TypeZ extends Map<Hest, Fisk>> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.textual_outline.expect
new file mode 100644
index 0000000..cd141ca
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import './non_simple_many_libs_same_name_cycle_lib.dart' as lib;
+
+class Hest<TypeX extends lib.Hest> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cd141ca
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import './non_simple_many_libs_same_name_cycle_lib.dart' as lib;
+
+class Hest<TypeX extends lib.Hest> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_no_dup.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_no_dup.dart.textual_outline.expect
new file mode 100644
index 0000000..9d9cb28
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_no_dup.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class Hest<TypeX extends Hest<TypeX>> {}
+
+class Fisk<TypeY extends Map<Hest, Hest>> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_no_dup.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_no_dup.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b11d407
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_no_dup.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+class Fisk<TypeY extends Map<Hest, Hest>> {}
+
+class Hest<TypeX extends Hest<TypeX>> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_suppress_consequence.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_suppress_consequence.dart.textual_outline.expect
new file mode 100644
index 0000000..98cfbeb
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_suppress_consequence.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class Hest<TypeX extends Hest<TypeX>> {}
+
+class Fisk<TypeY extends Hest> {}
+
+class Naebdyr<TypeZ extends Fisk> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_suppress_consequence.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_suppress_consequence.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..568af17
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_suppress_consequence.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class Fisk<TypeY extends Hest> {}
+
+class Hest<TypeX extends Hest<TypeX>> {}
+
+class Naebdyr<TypeZ extends Fisk> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_variables_from_same.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_variables_from_same.dart.textual_outline.expect
new file mode 100644
index 0000000..0755cda
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_variables_from_same.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class Hest<TypeX extends Hest<TypeX>> {}
+
+class Fisk<TypeY extends Hest> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_variables_from_same.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_variables_from_same.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b1177bb
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_variables_from_same.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+class Fisk<TypeY extends Hest> {}
+
+class Hest<TypeX extends Hest<TypeX>> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/omitted_bound.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/omitted_bound.dart.textual_outline.expect
new file mode 100644
index 0000000..6360eb1
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/omitted_bound.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+import 'dart:collection';
+
+class A<T> {}
+
+A a;
+DoubleLinkedQueue c;
+
+class C {
+ A foo() => null;
+ DoubleLinkedQueue baz() => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/omitted_bound.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/omitted_bound.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4d391e8
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/omitted_bound.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+import 'dart:collection';
+
+A a;
+DoubleLinkedQueue c;
+
+class A<T> {}
+
+class C {
+ A foo() => null;
+ DoubleLinkedQueue baz() => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/raw_in_bound.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/raw_in_bound.dart.textual_outline.expect
new file mode 100644
index 0000000..7391350
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/raw_in_bound.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class A<T extends num> {}
+
+class B<T extends A> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/raw_in_bound.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/raw_in_bound.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7391350
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/raw_in_bound.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+class A<T extends num> {}
+
+class B<T extends A> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.textual_outline.expect
new file mode 100644
index 0000000..f965240
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class A<X extends Comparable<X>> {}
+
+class B<Y extends A<dynamic>> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f965240
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_in_bound.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+class A<X extends Comparable<X>> {}
+
+class B<Y extends A<dynamic>> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/super_bounded_type.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_type.dart.textual_outline.expect
new file mode 100644
index 0000000..4293253
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_type.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class A<T extends A<T>> {}
+
+A a;
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/super_bounded_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c99abd3
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+A a;
+
+class A<T extends A<T>> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/supertypes.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/supertypes.dart.textual_outline.expect
new file mode 100644
index 0000000..7ff14a2
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/supertypes.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+import 'package:expect/expect.dart';
+
+class B {}
+
+class X<T extends B> {}
+
+class Y extends X {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/supertypes.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/supertypes.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7ff14a2
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/supertypes.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+import 'package:expect/expect.dart';
+
+class B {}
+
+class X<T extends B> {}
+
+class Y extends X {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_instantiated_in_outline.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_instantiated_in_outline.dart.textual_outline.expect
new file mode 100644
index 0000000..9d30ea1
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_instantiated_in_outline.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+typedef A<T extends num>(T p);
+
+class B {
+ foo(A a) => null;
+ A bar() => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_instantiated_in_outline.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_instantiated_in_outline.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..652f3ca
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_instantiated_in_outline.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class B {
+ A bar() => null;
+ foo(A a) => null;
+}
+
+main() {}
+typedef A<T extends num>(T p);
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list.dart.textual_outline.expect
new file mode 100644
index 0000000..62a0a7e
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+typedef A<T extends num>(T p);
+var a = <A>[];
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f07241b
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+main() {}
+typedef A<T extends num>(T p);
+var a = <A>[];
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list_with_generic_argument.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list_with_generic_argument.dart.textual_outline.expect
new file mode 100644
index 0000000..9b7bab7
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list_with_generic_argument.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+typedef A<T>(T p);
+
+class B<S> {
+ final List<A<S>> foo = <A<S>>[];
+ final List<A<num>> bar = <A<num>>[];
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list_with_generic_argument.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list_with_generic_argument.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..86ca2d6
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list_with_generic_argument.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class B<S> {
+ final List<A<S>> foo = <A<S>>[];
+ final List<A<num>> bar = <A<num>>[];
+}
+
+main() {}
+typedef A<T>(T p);
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_map.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_map.dart.textual_outline.expect
new file mode 100644
index 0000000..8924ab9
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_map.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+typedef A<T extends num>(T p);
+var a = <A, A>{};
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_map.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_map.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b88eb51
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_map.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+main() {}
+typedef A<T extends num>(T p);
+var a = <A, A>{};
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_omitted_bound.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_omitted_bound.dart.textual_outline.expect
new file mode 100644
index 0000000..5eb24cf
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_omitted_bound.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+typedef A<T>(T p);
+A a;
+
+class C {
+ A foo() => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_omitted_bound.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_omitted_bound.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1af4af2
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_omitted_bound.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+A a;
+
+class C {
+ A foo() => null;
+}
+
+main() {}
+typedef A<T>(T p);
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_raw_in_bound.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_raw_in_bound.dart.textual_outline.expect
new file mode 100644
index 0000000..f90dddc
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_raw_in_bound.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+typedef A<T extends num>(T p);
+
+class B<T extends A> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_raw_in_bound.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_raw_in_bound.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fb74707
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_raw_in_bound.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+class B<T extends A> {}
+
+main() {}
+typedef A<T extends num>(T p);
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_super_bounded_type.dart.textual_outline.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_super_bounded_type.dart.textual_outline.expect
new file mode 100644
index 0000000..4e39887
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_super_bounded_type.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+typedef A<T>(T p);
+typedef B<S extends A<S>>(S p);
+B b;
+main() {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_super_bounded_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_super_bounded_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..becf3c9
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_super_bounded_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+B b;
+main() {}
+typedef A<T>(T p);
+typedef B<S extends A<S>>(S p);
diff --git a/pkg/front_end/testcases/late_lowering/compound.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/compound.dart.textual_outline.expect
new file mode 100644
index 0000000..69ffc5c
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/compound.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+main() {}
+error() {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/late_lowering/compound.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/late_lowering/compound.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2780646
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/compound.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+error() {}
+expect(expected, actual) {}
+main() {}
diff --git a/pkg/front_end/testcases/late_lowering/definitely_assigned.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/definitely_assigned.dart.textual_outline.expect
new file mode 100644
index 0000000..1932ec0
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/definitely_assigned.dart.textual_outline.expect
@@ -0,0 +1,45 @@
+import 'dart:async';
+
+methodDirect<T>(T value) {}
+var fieldDirect = <T>(T value) {
+ late;
+ final T local2;
+ late;
+ final int local4;
+ late;
+ final FutureOr<int> local6;
+ local2 = value;
+ local4 = 0;
+ local6 = 0;
+ local2 = value;
+ local4 = 0;
+ local6 = 0;
+};
+methodConditional<T>(bool b, T value) {}
+var fieldConditional = <T>(bool b, T value) {
+ late;
+ final T local2;
+ late;
+ final int local4;
+ late;
+ final FutureOr<int> local6;
+ if (b) {
+ local2 = value;
+ local4 = 0;
+ local6 = 0;
+ }
+ local2 = value;
+ local4 = 0;
+ local6 = 0;
+ local2 = value;
+ local4 = 0;
+ local6 = 0;
+};
+methodCompound() {}
+var fieldCompound = () {
+ late;
+ final int local4;
+ local4 = 0;
+ local4 += 0;
+};
+main() {}
diff --git a/pkg/front_end/testcases/late_lowering/definitely_assigned.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/late_lowering/definitely_assigned.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..be04eb0
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/definitely_assigned.dart.textual_outline_modelled.expect
@@ -0,0 +1,45 @@
+import 'dart:async';
+
+main() {}
+methodCompound() {}
+methodConditional<T>(bool b, T value) {}
+methodDirect<T>(T value) {}
+var fieldCompound = () {
+ late;
+ final int local4;
+ local4 = 0;
+ local4 += 0;
+};
+var fieldConditional = <T>(bool b, T value) {
+ late;
+ final T local2;
+ late;
+ final int local4;
+ late;
+ final FutureOr<int> local6;
+ if (b) {
+ local2 = value;
+ local4 = 0;
+ local6 = 0;
+ }
+ local2 = value;
+ local4 = 0;
+ local6 = 0;
+ local2 = value;
+ local4 = 0;
+ local6 = 0;
+};
+var fieldDirect = <T>(T value) {
+ late;
+ final T local2;
+ late;
+ final int local4;
+ late;
+ final FutureOr<int> local6;
+ local2 = value;
+ local4 = 0;
+ local6 = 0;
+ local2 = value;
+ local4 = 0;
+ local6 = 0;
+};
diff --git a/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.textual_outline.expect
new file mode 100644
index 0000000..f27c6c0
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.textual_outline.expect
@@ -0,0 +1,64 @@
+import 'dart:async';
+
+methodDirect<T>(T value) {}
+var fieldDirect = <T>(T value) {
+ T local1;
+ late T;
+ local2;
+ int local3;
+ late int;
+ local4;
+ FutureOr<int> local5;
+ late FutureOr;
+ <int>[];
+ local6;
+ late T;
+ local7 = value;
+ local1;
+ local2;
+ local3;
+ local4;
+ local5;
+ local6;
+ local7;
+};
+methodConditional<T>(bool b, T value) {}
+var fieldConditional = <T>(bool b, T value) {
+ T local1;
+ late T;
+ local2;
+ int local3;
+ late int;
+ local4;
+ FutureOr<int> local5;
+ late FutureOr;
+ <int>[];
+ local6;
+ late T;
+ local7 = value;
+ if (b) {
+ local1 = value;
+ local2 = value;
+ local3 = 0;
+ local4 = 0;
+ local5 = 0;
+ local6 = 0;
+ local7;
+ }
+ local1;
+ local2;
+ local3;
+ local4;
+ local5;
+ local6;
+ local7;
+};
+methodCompound() {}
+var fieldCompound = () {
+ int local3;
+ late int;
+ local4;
+ local3 += 0;
+ local4 += 0;
+};
+main() {}
diff --git a/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..46a4371
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/definitely_unassigned.dart.textual_outline_modelled.expect
@@ -0,0 +1,64 @@
+import 'dart:async';
+
+main() {}
+methodCompound() {}
+methodConditional<T>(bool b, T value) {}
+methodDirect<T>(T value) {}
+var fieldCompound = () {
+ int local3;
+ late int;
+ local4;
+ local3 += 0;
+ local4 += 0;
+};
+var fieldConditional = <T>(bool b, T value) {
+ T local1;
+ late T;
+ local2;
+ int local3;
+ late int;
+ local4;
+ FutureOr<int> local5;
+ late FutureOr;
+ <int>[];
+ local6;
+ late T;
+ local7 = value;
+ if (b) {
+ local1 = value;
+ local2 = value;
+ local3 = 0;
+ local4 = 0;
+ local5 = 0;
+ local6 = 0;
+ local7;
+ }
+ local1;
+ local2;
+ local3;
+ local4;
+ local5;
+ local6;
+ local7;
+};
+var fieldDirect = <T>(T value) {
+ T local1;
+ late T;
+ local2;
+ int local3;
+ late int;
+ local4;
+ FutureOr<int> local5;
+ late FutureOr;
+ <int>[];
+ local6;
+ late T;
+ local7 = value;
+ local1;
+ local2;
+ local3;
+ local4;
+ local5;
+ local6;
+ local7;
+};
diff --git a/pkg/front_end/testcases/late_lowering/infer_from_late_variable.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/infer_from_late_variable.dart.textual_outline.expect
new file mode 100644
index 0000000..0ce51c7
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/infer_from_late_variable.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+T f<T>(T t) => t;
+main() {}
diff --git a/pkg/front_end/testcases/late_lowering/infer_from_late_variable.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/late_lowering/infer_from_late_variable.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0ce51c7
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/infer_from_late_variable.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+T f<T>(T t) => t;
+main() {}
diff --git a/pkg/front_end/testcases/late_lowering/infer_late_field_type.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/infer_late_field_type.dart.textual_outline.expect
new file mode 100644
index 0000000..ec3d9da
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/infer_late_field_type.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+class A {
+ int? field;
+}
+class B implements A {
+ late ;
+ var field;
+}
+main() { }
diff --git a/pkg/front_end/testcases/late_lowering/initializer_rewrite.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/initializer_rewrite.dart.textual_outline.expect
new file mode 100644
index 0000000..aea51f7
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/initializer_rewrite.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+int nonNullableTopLevelFieldReads = 0;
+late ;
+final int nonNullableTopLevelField = nonNullableTopLevelFieldReads++ == 0 ? nonNullableTopLevelField + 1 : 0;
+int nullableTopLevelFieldReads = 0;
+late ;
+final int? nullableTopLevelField = nullableTopLevelFieldReads++ == 0 ? nullableTopLevelField.hashCode : 0;
+class Class {
+ static int nonNullableStaticFieldReads = 0;
+ static late ;
+ final int nonNullableStaticField = nonNullableStaticFieldReads++ == 0 ? nonNullableStaticField + 1 : 0;
+ static int nullableStaticFieldReads = 0;
+ static late ;
+ final int? nullableStaticField = nullableStaticFieldReads++ == 0 ? nullableStaticField.hashCode : 0;
+ int nonNullableInstanceFieldReads = 0;
+ late ;
+ final int nonNullableInstanceField = nonNullableInstanceFieldReads++ == 0 ? nonNullableInstanceField + 1 : 0;
+ int nullableInstanceFieldReads = 0;
+ late ;
+ final int? nullableInstanceField = nullableInstanceFieldReads++ == 0 ? nullableInstanceField.hashCode : 0;
+}
+void main() { }
+throws(f(), String message) { }
diff --git a/pkg/front_end/testcases/late_lowering/injected_late_field_checks/main.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/injected_late_field_checks/main.dart.textual_outline.expect
new file mode 100644
index 0000000..3c9c90e
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/injected_late_field_checks/main.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+import 'dart:test';
+
+main() {}
diff --git a/pkg/front_end/testcases/late_lowering/injected_late_field_checks/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/late_lowering/injected_late_field_checks/main.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3c9c90e
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/injected_late_field_checks/main.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+import 'dart:test';
+
+main() {}
diff --git a/pkg/front_end/testcases/late_lowering/instance_field_with_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/instance_field_with_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..25677b9
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/instance_field_with_initializer.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+class Class {
+ late int ;
+ field = 10;
+ Class.constructor1();
+ Class.constructor2(this.field);
+ Class.constructor3(int value) : this.field = value + 1;
+ Class.constructor4([this.field = 42]);
+}
+class Subclass extends Class {
+ Subclass.constructor1() : super.constructor1();
+ Subclass.constructor2(int value) : super.constructor2(value);
+ Subclass.constructor3(int value) : super.constructor3(value);
+ Subclass.constructor4([int value = 87]) : super.constructor4(value);
+}
+test1() { }
+test2() { }
+main() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/late_lowering/instance_field_without_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/instance_field_without_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..21809ff
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/instance_field_without_initializer.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+class Class {
+ late int ;
+ field;
+ Class.constructor1();
+ Class.constructor2(this.field);
+ Class.constructor3(int value) : this.field = value + 1;
+ Class.constructor4([this.field = 42]);
+}
+class Subclass extends Class {
+ Subclass.constructor1() : super.constructor1();
+ Subclass.constructor2(int value) : super.constructor2(value);
+ Subclass.constructor3(int value) : super.constructor3(value);
+ Subclass.constructor4([int value = 87]) : super.constructor4(value);
+}
+test1() { }
+test2() { }
+main() { }
+expect(expected, actual) { }
+throws(f(), String message) { }
diff --git a/pkg/front_end/testcases/late_lowering/instance_final_field_without_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/instance_final_field_without_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..3a3d178
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/instance_final_field_without_initializer.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+class Class {
+ late ;
+ final int field;
+ Class.constructor1();
+ Class.constructor2(this.field);
+ Class.constructor3(int value) : this.field = value + 1;
+ Class.constructor4([this.field = 42]);
+}
+class Subclass extends Class {
+ Subclass.constructor1() : super.constructor1();
+ Subclass.constructor2(int value) : super.constructor2(value);
+ Subclass.constructor3(int value) : super.constructor3(value);
+ Subclass.constructor4([int value = 87]) : super.constructor4(value);
+}
+test1() { }
+test2() { }
+main() { }
+expect(expected, actual) { }
+throws(f(), String message) { }
diff --git a/pkg/front_end/testcases/late_lowering/instance_nullable_field_with_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/instance_nullable_field_with_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..3102d50
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/instance_nullable_field_with_initializer.dart.textual_outline.expect
@@ -0,0 +1,20 @@
+int? initField() => 10;
+class Class {
+ late int;
+ operator? ( ){ }
+ field = initField();
+ Class.constructor1();
+ Class.constructor2(this.field);
+ Class.constructor3(int value) : this.field = value + 1;
+ Class.constructor4([this.field = 42]);
+}
+class Subclass extends Class {
+ Subclass.constructor1() : super.constructor1();
+ Subclass.constructor2(int value) : super.constructor2(value);
+ Subclass.constructor3(int value) : super.constructor3(value);
+ Subclass.constructor4([int value = 87]) : super.constructor4(value);
+}
+test1() { }
+test2() { }
+main() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/late_lowering/instance_nullable_field_without_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/instance_nullable_field_without_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..9196f4b
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/instance_nullable_field_without_initializer.dart.textual_outline.expect
@@ -0,0 +1,20 @@
+class Class {
+ late int;
+ operator? ( ){ }
+ field;
+ Class.constructor1();
+ Class.constructor2(this.field);
+ Class.constructor3(int value) : this.field = value + 1;
+ Class.constructor4([this.field = 42]);
+}
+class Subclass extends Class {
+ Subclass.constructor1() : super.constructor1();
+ Subclass.constructor2(int value) : super.constructor2(value);
+ Subclass.constructor3(int value) : super.constructor3(value);
+ Subclass.constructor4([int value = 87]) : super.constructor4(value);
+}
+test1() { }
+test2() { }
+main() { }
+expect(expected, actual) { }
+throws(f(), String message) { }
diff --git a/pkg/front_end/testcases/late_lowering/instance_nullable_final_field_without_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/instance_nullable_final_field_without_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..2d9596f
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/instance_nullable_final_field_without_initializer.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+class Class {
+ late ;
+ final int? field;
+ Class.constructor1();
+ Class.constructor2(this.field);
+ Class.constructor3(int value) : this.field = value + 1;
+ Class.constructor4([this.field = 42]);
+}
+class Subclass extends Class {
+ Subclass.constructor1() : super.constructor1();
+ Subclass.constructor2(int value) : super.constructor2(value);
+ Subclass.constructor3(int value) : super.constructor3(value);
+ Subclass.constructor4([int value = 87]) : super.constructor4(value);
+}
+test1() { }
+test2() { }
+main() { }
+expect(expected, actual) { }
+throws(f(), String message) { }
diff --git a/pkg/front_end/testcases/late_lowering/issue40093.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/issue40093.dart.textual_outline.expect
new file mode 100644
index 0000000..c7e2924
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue40093.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+error() {}
+main() {}
diff --git a/pkg/front_end/testcases/late_lowering/issue40093.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/late_lowering/issue40093.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c7e2924
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue40093.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+error() {}
+main() {}
diff --git a/pkg/front_end/testcases/late_lowering/issue40373.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/issue40373.dart.textual_outline.expect
new file mode 100644
index 0000000..233c4a9
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue40373.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class C {
+ num pi = 3.14;
+ late num ;
+ p1 = this.pi;
+ late ;
+ final p2 = this.pi;
+}
+main() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/late_lowering/issue40373b.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/issue40373b.dart.textual_outline.expect
new file mode 100644
index 0000000..e89731e
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue40373b.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+late ;
+final g;
+class C {
+ static late ;
+ final s;
+ late ;
+ final v;
+}
+main() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/late_lowering/issue40601.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/issue40601.dart.textual_outline.expect
new file mode 100644
index 0000000..96d9d0d
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue40601.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+abstract class A<T> {
+ T baz();
+ bar(T value) {}
+ foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/late_lowering/issue40601.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/late_lowering/issue40601.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..96d9d0d
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue40601.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+abstract class A<T> {
+ T baz();
+ bar(T value) {}
+ foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/late_lowering/issue40805.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/issue40805.dart.textual_outline.expect
new file mode 100644
index 0000000..4c9d91e
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue40805.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+main() { }
+class C {
+ covariant late ;
+ final int x;
+}
+class D extends C {
+ set x(num value) { }
+}
diff --git a/pkg/front_end/testcases/late_lowering/issue41436/issue41436.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/issue41436/issue41436.dart.textual_outline.expect
new file mode 100644
index 0000000..3c9c90e
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue41436/issue41436.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+import 'dart:test';
+
+main() {}
diff --git a/pkg/front_end/testcases/late_lowering/issue41436/issue41436.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/late_lowering/issue41436/issue41436.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3c9c90e
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue41436/issue41436.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+import 'dart:test';
+
+main() {}
diff --git a/pkg/front_end/testcases/late_lowering/issue41436b.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/issue41436b.dart.textual_outline.expect
new file mode 100644
index 0000000..7b9adf1
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue41436b.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+abstract class A {
+ late int ;
+ x;
+}
+class _B implements A {
+ int x = 3;
+}
+main() { }
diff --git a/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c.dart.textual_outline.expect
new file mode 100644
index 0000000..016393b
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'issue41436c_lib.dart';
+
+class C extends B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..016393b
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue41436c/issue41436c.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import 'issue41436c_lib.dart';
+
+class C extends B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/late_lowering/late_field_inference.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_field_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..ec35e3c
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_field_inference.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+int? method() => null;
+late ;
+var nonNullableTopLevelField = 0;
+late ;
+var nullableTopLevelField = method();
+class A {
+ late ;
+ var nonNullableInstanceField = 0;
+ late ;
+ var nullableInstanceField = method();
+ static late ;
+ var nonNullableStaticField = 0;
+ static late ;
+ var nullableStaticField = method();
+}
+class B extends A {
+ get nonNullableInstanceField => 0;
+ set nonNullableInstanceField(value) { }
+ get nullableInstanceField => 0;
+ set nullableInstanceField(value) { }
+}
+main() { }
diff --git a/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..659d61d
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+late int ;
+lateTopLevelField1 = 123;
+class Class<T> {
+ static late int ;
+ lateStaticField1 = 87;
+ static late int ;
+ lateStaticField2 = 42;
+ static staticMethod() { }
+ late int ;
+ lateInstanceField = 16;
+ final T field;
+ late T ;
+ lateGenericField1 = field;
+ late T ;
+ lateGenericField2 = field;
+ Class(this.field);
+ instanceMethod(T value) { }
+}
+extension Extension<T> ( ){ }
+on Class<T> (){ }
+main() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..3db9332
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+late int ;
+lateTopLevelField;
+class Class<T> {
+ static late int ;
+ lateStaticField1;
+ static late int ;
+ lateStaticField2;
+ static staticMethod() { }
+ late int ;
+ lateInstanceField;
+ late T ;
+ lateGenericInstanceField;
+ instanceMethod(T value) { }
+}
+extension Extension<T> ( ){ }
+on Class<T> (){ }
+main() { }
+expect(expected, actual) { }
+throws(f(), String message) { }
diff --git a/pkg/front_end/testcases/late_lowering/late_final_field_with_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_final_field_with_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..8785f2d
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_final_field_with_initializer.dart.textual_outline.expect
@@ -0,0 +1,30 @@
+int? lateTopLevelField1Init;
+int initLateTopLevelField1(int value) { }
+late ;
+final int lateTopLevelField1 = initLateTopLevelField1(123);
+class Class<T> {
+ static int? lateStaticField1Init;
+ static int initLateStaticField1(int value) { }
+ static late ;
+ final int lateStaticField1 = initLateStaticField1(87);
+ static int? lateStaticField2Init;
+ static int initLateStaticField2(int value) { }
+ static late ;
+ final int lateStaticField2 = initLateStaticField2(42);
+ static staticMethod() { }
+ int? lateInstanceFieldInit;
+ int initLateInstanceField(int value) { }
+ late ;
+ final int lateInstanceField = initLateInstanceField(16);
+ T? lateGenericFieldInit;
+ T initLateGenericField(T value) { }
+ final T field;
+ late ;
+ final T lateGenericField = initLateGenericField(field);
+ Class(this.field);
+ instanceMethod() { }
+}
+extension Extension<T> ( ){ }
+on Class<T> (){ }
+main() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..3f83924
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+late ;
+final int lateTopLevelField;
+class Class {
+ static late ;
+ final int lateStaticField1;
+ static late ;
+ final int lateStaticField2;
+ static staticMethod() { }
+ late ;
+ final int lateInstanceField;
+ instanceMethod() { }
+}
+extension Extension ;
+on Class (){ }
+main() { }
+expect(expected, actual) { }
+throws(f(), String message) { }
diff --git a/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..456a9fa
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+main() {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d8c8350
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+expect(expected, actual) {}
+main() {}
diff --git a/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..cb1533c
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+main() {}
+expect(expected, actual) {}
+throws(f(), String message) {}
diff --git a/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9105f4a
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_final_local_without_initializer.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+expect(expected, actual) {}
+main() {}
+throws(f(), String message) {}
diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_field_with_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_with_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..38ba267
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_with_initializer.dart.textual_outline.expect
@@ -0,0 +1,30 @@
+int? lateTopLevelField1Init;
+int? initLateTopLevelField1(int value) { }
+late ;
+final int? lateTopLevelField1 = initLateTopLevelField1(123);
+class Class<T> {
+ static int? lateStaticField1Init;
+ static int? initLateStaticField1(int value) { }
+ static late ;
+ final int? lateStaticField1 = initLateStaticField1(87);
+ static int? lateStaticField2Init;
+ static int? initLateStaticField2(int value) { }
+ static late ;
+ final int? lateStaticField2 = initLateStaticField2(42);
+ static staticMethod() { }
+ int? lateInstanceFieldInit;
+ int? initLateInstanceField(int value) { }
+ late ;
+ final int? lateInstanceField = initLateInstanceField(16);
+ T? lateGenericInstanceFieldInit;
+ T? initLateGenericInstanceField(T? value) { }
+ final T? field;
+ late ;
+ final T? lateGenericInstanceField = initLateGenericInstanceField(field);
+ Class(this.field);
+ instanceMethod() { }
+}
+extension Extension<T> ( ){ }
+on Class<T> (){ }
+main() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..e23b4bf
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+late ;
+final int? lateTopLevelField;
+class Class<T> {
+ static late ;
+ final int? lateStaticField1;
+ static late ;
+ final int? lateStaticField2;
+ static staticMethod() { }
+ late ;
+ final int? lateInstanceField;
+ late ;
+ final T? lateGenericInstanceField;
+ instanceMethod(T value) { }
+}
+extension Extension<T> ( ){ }
+on Class<T> (){ }
+main() { }
+expect(expected, actual) { }
+throws(f(), String message) { }
diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..456a9fa
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+main() {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d8c8350
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+expect(expected, actual) {}
+main() {}
diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_local_without_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_without_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..cb1533c
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_without_initializer.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+main() {}
+expect(expected, actual) {}
+throws(f(), String message) {}
diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_local_without_initializer.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_without_initializer.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9105f4a
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_without_initializer.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+expect(expected, actual) {}
+main() {}
+throws(f(), String message) {}
diff --git a/pkg/front_end/testcases/late_lowering/late_future_or.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_future_or.dart.textual_outline.expect
new file mode 100644
index 0000000..af64f8b
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_future_or.dart.textual_outline.expect
@@ -0,0 +1,35 @@
+import 'dart:async';
+FutureOr method1() => null;
+FutureOr? method2() => null;
+FutureOr<dynamic> method3() => null;
+FutureOr<int> method4() => 0;
+FutureOr<int?> method5() => null;
+FutureOr<int?>? method6() => null;
+late ;
+var field1 = method1();
+late ;
+var field2 = method2();
+late ;
+var field3 = method3();
+late ;
+var field4 = method4();
+late ;
+var field5 = method5();
+late ;
+var field6 = method6();
+class C<T> {
+ late FutureOr ;
+ field1;
+ late FutureOr;
+ operator? ( ){ }
+ field2;
+ late FutureOr<T> ( ){ }
+ field3;
+ late FutureOr<T?> ( ){ }
+ field4;
+ late FutureOr<T?>( ){ }
+ operator? ( ){ }
+ field5;
+ method() { }
+}
+main() { }
diff --git a/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..456a9fa
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+main() {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d8c8350
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_local_with_initializer.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+expect(expected, actual) {}
+main() {}
diff --git a/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..cb1533c
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+main() {}
+expect(expected, actual) {}
+throws(f(), String message) {}
diff --git a/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9105f4a
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_local_without_initializer.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+expect(expected, actual) {}
+main() {}
+throws(f(), String message) {}
diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..d3feb52
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.textual_outline.expect
@@ -0,0 +1,30 @@
+int? lateTopLevelField1Init() => 123;
+late int;
+?
+lateTopLevelField1 = lateTopLevelField1Init();
+class Class<T> {
+ static int? lateStaticField1Init() => 87;
+ static late int;
+ operator? ( ){ }
+ lateStaticField1 = lateStaticField1Init();
+ static int? lateStaticField2Init() => 42;
+ static late int;
+ operator? ( ){ }
+ lateStaticField2 = lateStaticField2Init();
+ static staticMethod() { }
+ int? lateInstanceFieldInit() => 16;
+ late int;
+ operator? ( ){ }
+ lateInstanceField = lateInstanceFieldInit();
+ final T? field;
+ T? lateGenericInstanceFieldInit() => field;
+ late T;
+ operator? ( ){ }
+ lateGenericInstanceField = lateGenericInstanceFieldInit();
+ Class(this.field);
+ instanceMethod(T? value) { }
+}
+extension Extension<T> ( ){ }
+on Class<T> (){ }
+main() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..bbebbdb
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.textual_outline.expect
@@ -0,0 +1,24 @@
+late int;
+?
+lateTopLevelField;
+class Class<T> {
+ static late int;
+ operator? ( ){ }
+ lateStaticField1;
+ static late int;
+ operator? ( ){ }
+ lateStaticField2;
+ static staticMethod() { }
+ late int;
+ operator? ( ){ }
+ lateInstanceField;
+ late T;
+ operator? ( ){ }
+ lateGenericInstanceField;
+ instanceMethod(T? value) { }
+}
+extension Extension<T> ( ){ }
+on Class<T> (){ }
+main() { }
+expect(expected, actual) { }
+throws(f(), String message) { }
diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..b491e36
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+int? lateLocalInit() => 123;
+main() {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9af13bc
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_nullable_local_with_initializer.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+expect(expected, actual) {}
+int? lateLocalInit() => 123;
+main() {}
diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_local_without_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/late_nullable_local_without_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..cb1533c
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_nullable_local_without_initializer.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+main() {}
+expect(expected, actual) {}
+throws(f(), String message) {}
diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_local_without_initializer.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/late_lowering/late_nullable_local_without_initializer.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9105f4a
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/late_nullable_local_without_initializer.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+expect(expected, actual) {}
+main() {}
+throws(f(), String message) {}
diff --git a/pkg/front_end/testcases/late_lowering/later.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/later.dart.textual_outline.expect
new file mode 100644
index 0000000..cb89651
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/later.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+// @dart = 2.9999
+class A {
+ int a = 42;
+ late int ;
+ b = (this.a * 2) >> 1;
+ foo(late int x) { }
+}
+bar(late int x) { }
+baz() { }
+hest() async { }
+fisk() async { }
+class B {
+ late ;
+ final int x = 42;
+ const B();
+}
+class C {
+ late ;
+ final int x;
+ initVars() { }
+}
+main() { }
diff --git a/pkg/front_end/testcases/late_lowering/override.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/override.dart.textual_outline.expect
new file mode 100644
index 0000000..66a20aa
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/override.dart.textual_outline.expect
@@ -0,0 +1,29 @@
+class Class {
+ late int ;
+ field1;
+ late int ;
+ field2;
+ late ;
+ final int field3;
+ late ;
+ final int field4;
+}
+class SubClass extends Class {
+ late int ;
+ field1;
+ late int ;
+ field2 = 0;
+ late ;
+ final int field3;
+ late ;
+ final int field4 = 0;
+ int get directField1 => super.field1;
+ void set directField1(int value) { }
+ int get directField2 => super.field2;
+ void set directField2(int value) { }
+ int get directField3 => super.field3;
+ int get directField4 => super.field4;
+}
+main() { }
+expect(expected, actual) { }
+throws(f(), String message) { }
diff --git a/pkg/front_end/testcases/late_lowering/override_getter_setter.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/override_getter_setter.dart.textual_outline.expect
new file mode 100644
index 0000000..7bf8597
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/override_getter_setter.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+class A {
+ late ;
+ final int x;
+ late ;
+ final int? y;
+}
+class B extends A {
+ int get x => 1;
+ int? get y => 1;
+}
+class C extends A {
+ late ;
+ final int x = 2;
+ late ;
+ final int? y = 2;
+}
+main() { }
+expect(expected, actual) { }
+throws(f(), String message) { }
diff --git a/pkg/front_end/testcases/late_lowering/return_late.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/return_late.dart.textual_outline.expect
new file mode 100644
index 0000000..3d93fd2
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/return_late.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class Class<E> {
+ final E field;
+ Class(this.field);
+ E returnTypeVariable() {}
+}
+
+int returnNonNullable(int value) {}
+int? returnNullable(int? value) {}
+main() {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/late_lowering/return_late.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/late_lowering/return_late.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e1ef11f
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/return_late.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+class Class<E> {
+ Class(this.field);
+ E returnTypeVariable() {}
+ final E field;
+}
+
+expect(expected, actual) {}
+int returnNonNullable(int value) {}
+int? returnNullable(int? value) {}
+main() {}
diff --git a/pkg/front_end/testcases/late_lowering/uninitialized_non_nullable_late_fields.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/uninitialized_non_nullable_late_fields.dart.textual_outline.expect
new file mode 100644
index 0000000..86269fb
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/uninitialized_non_nullable_late_fields.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class A {
+ late int ;
+ x;
+ A.foo(this.x);
+ A.bar();
+}
+main() { }
diff --git a/pkg/front_end/testcases/new_const_insertion/simple.dart.textual_outline.expect b/pkg/front_end/testcases/new_const_insertion/simple.dart.textual_outline.expect
new file mode 100644
index 0000000..e387ab9
--- /dev/null
+++ b/pkg/front_end/testcases/new_const_insertion/simple.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class A {
+ final int x;
+ const A(this.x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/new_const_insertion/simple.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/new_const_insertion/simple.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2c15976
--- /dev/null
+++ b/pkg/front_end/testcases/new_const_insertion/simple.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class A {
+ const A(this.x);
+ final int x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/assign_type_variable.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/assign_type_variable.dart.textual_outline.expect
new file mode 100644
index 0000000..57b1335
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/assign_type_variable.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class Class<E> {
+ void method(E e) {}
+}
+
+T id<T>(T t) => t;
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/assign_type_variable.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/assign_type_variable.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0f46f8a
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/assign_type_variable.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+T id<T>(T t) => t;
+
+class Class<E> {
+ void method(E e) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/assignability.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/assignability.dart.textual_outline.expect
new file mode 100644
index 0000000..1197640
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/assignability.dart.textual_outline.expect
@@ -0,0 +1,49 @@
+class Tearoffable {
+ void call() {}
+}
+
+ok<
+ XnonNull extends Object,
+ YnonNull extends XnonNull,
+ XpotentiallyNull extends Object?,
+ YpotentiallyNull extends XpotentiallyNull>(
+ dynamic dynamicArg,
+ Object objectArg,
+ num numArg,
+ int intArg,
+ double doubleArg,
+ Function functionArg,
+ void Function() toVoidArg,
+ Tearoffable tearoffableArg,
+ XnonNull xNonNullArg,
+ XpotentiallyNull xPotentiallyNullArg,
+ YnonNull yNonNullArg,
+ YpotentiallyNull yPotentiallyNullArg) {}
+error<
+ XnonNull extends Object,
+ YnonNull extends XnonNull,
+ XpotentiallyNull extends Object?,
+ YpotentiallyNull extends XpotentiallyNull>(
+ Object objectArg,
+ Object? objectNullableArg,
+ num numArg,
+ num? numNullableArg,
+ int intArg,
+ int? intNullableArg,
+ double doubleArg,
+ double? doubleNullableArg,
+ Function functionArg,
+ Function? functionNullableArg,
+ void Function() toVoidArg,
+ void Function()? toVoidNullableArg,
+ Tearoffable tearoffableArg,
+ Tearoffable? tearoffableNullableArg,
+ XnonNull xNonNullArg,
+ XnonNull? xNonNullNullableArg,
+ XpotentiallyNull xPotentiallyNullArg,
+ XpotentiallyNull? xPotentiallyNullNullableArg,
+ YnonNull yNonNullArg,
+ YnonNull? yNonNullNullableArg,
+ YpotentiallyNull yPotentiallyNullArg,
+ YpotentiallyNull? yPotentiallyNullNullableArg) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/assignability.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/assignability.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..23eaee3
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/assignability.dart.textual_outline_modelled.expect
@@ -0,0 +1,49 @@
+class Tearoffable {
+ void call() {}
+}
+
+error<
+ XnonNull extends Object,
+ YnonNull extends XnonNull,
+ XpotentiallyNull extends Object?,
+ YpotentiallyNull extends XpotentiallyNull>(
+ Object objectArg,
+ Object? objectNullableArg,
+ num numArg,
+ num? numNullableArg,
+ int intArg,
+ int? intNullableArg,
+ double doubleArg,
+ double? doubleNullableArg,
+ Function functionArg,
+ Function? functionNullableArg,
+ void Function() toVoidArg,
+ void Function()? toVoidNullableArg,
+ Tearoffable tearoffableArg,
+ Tearoffable? tearoffableNullableArg,
+ XnonNull xNonNullArg,
+ XnonNull? xNonNullNullableArg,
+ XpotentiallyNull xPotentiallyNullArg,
+ XpotentiallyNull? xPotentiallyNullNullableArg,
+ YnonNull yNonNullArg,
+ YnonNull? yNonNullNullableArg,
+ YpotentiallyNull yPotentiallyNullArg,
+ YpotentiallyNull? yPotentiallyNullNullableArg) {}
+main() {}
+ok<
+ XnonNull extends Object,
+ YnonNull extends XnonNull,
+ XpotentiallyNull extends Object?,
+ YpotentiallyNull extends XpotentiallyNull>(
+ dynamic dynamicArg,
+ Object objectArg,
+ num numArg,
+ int intArg,
+ double doubleArg,
+ Function functionArg,
+ void Function() toVoidArg,
+ Tearoffable tearoffableArg,
+ XnonNull xNonNullArg,
+ XpotentiallyNull xPotentiallyNullArg,
+ YnonNull yNonNullArg,
+ YpotentiallyNull yPotentiallyNullArg) {}
diff --git a/pkg/front_end/testcases/nnbd/bounds_checks.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/bounds_checks.dart.textual_outline.expect
new file mode 100644
index 0000000..8827b4d
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/bounds_checks.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+class A<X extends num> {}
+
+foo(A<num?> a) {}
+A<num?>? bar() {}
+baz<T extends A<num?>>() {}
+
+class B extends A<num?> {}
+
+class C<T extends A<num?>> {}
+
+void hest<T extends num>() {}
+
+class Hest {
+ void hest<T extends num>() {}
+}
+
+fisk(Hest h) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/bounds_checks.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/bounds_checks.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9c93979
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/bounds_checks.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+A<num?>? bar() {}
+baz<T extends A<num?>>() {}
+
+class A<X extends num> {}
+
+class B extends A<num?> {}
+
+class C<T extends A<num?>> {}
+
+class Hest {
+ void hest<T extends num>() {}
+}
+
+fisk(Hest h) {}
+foo(A<num?> a) {}
+main() {}
+void hest<T extends num>() {}
diff --git a/pkg/front_end/testcases/nnbd/bounds_from_opt_in.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/bounds_from_opt_in.dart.textual_outline.expect
new file mode 100644
index 0000000..fb1115b
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/bounds_from_opt_in.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+import 'bounds_from_opt_in_lib.dart';
+
+class LegacyClass<T extends Null> extends Class<T> {
+ method<T extends Null>() {}
+}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/bounds_from_opt_in.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/bounds_from_opt_in.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8221626
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/bounds_from_opt_in.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+import 'bounds_from_opt_in_lib.dart';
+
+class LegacyClass<T extends Null> extends Class<T> {
+ method<T extends Null>() {}
+}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/nnbd/call.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/call.dart.textual_outline.expect
new file mode 100644
index 0000000..d90b603
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/call.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class Class {
+ void Function()? field;
+ void Function()? get getter => null;
+}
+
+error() {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/call.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/call.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d90b603
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/call.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class Class {
+ void Function()? field;
+ void Function()? get getter => null;
+}
+
+error() {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/constant_null_is.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/constant_null_is.dart.textual_outline.expect
new file mode 100644
index 0000000..93feb55
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/constant_null_is.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+import 'dart:async';
+import 'constant_null_is_lib.dart';
+
+const c0 = null is int?;
+const c1 = null is int;
+const c2 = null is Null;
+const c3 = null is Never?;
+const c4 = null is Never;
+const c5 = null is FutureOr<int?>;
+const c6 = null is FutureOr<int>;
+const c7 = null is FutureOr<int>?;
+const c8 = null is FutureOr<Null>;
+const c9 = null is FutureOr<Null>?;
+const c10 = null is FutureOr<Never>;
+const c11 = null is FutureOr<Never?>;
+const c12 = null is FutureOr<Never>?;
+main() {}
+expect(expected, actual, String message) {}
diff --git a/pkg/front_end/testcases/nnbd/constant_null_is.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/constant_null_is.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..04683eb
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/constant_null_is.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+import 'dart:async';
+import 'constant_null_is_lib.dart';
+
+const c0 = null is int?;
+const c1 = null is int;
+const c10 = null is FutureOr<Never>;
+const c11 = null is FutureOr<Never?>;
+const c12 = null is FutureOr<Never>?;
+const c2 = null is Null;
+const c3 = null is Never?;
+const c4 = null is Never;
+const c5 = null is FutureOr<int?>;
+const c6 = null is FutureOr<int>;
+const c7 = null is FutureOr<int>?;
+const c8 = null is FutureOr<Null>;
+const c9 = null is FutureOr<Null>?;
+expect(expected, actual, String message) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/constants.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/constants.dart.textual_outline.expect
new file mode 100644
index 0000000..abf8e2f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/constants.dart.textual_outline.expect
@@ -0,0 +1,37 @@
+import 'constants_lib.dart' as lib;
+
+typedef F1<T> = T Function(T);
+typedef F2 = T Function<T>(T);
+const objectTypeLiteral = Object;
+const int Function(int) partialInstantiation = lib.id;
+const instance = const lib.Class<int>(0);
+const functionTypeLiteral = F1;
+const genericFunctionTypeLiteral = F2;
+const listLiteral = <int>[0];
+const setLiteral = <int>{0};
+const mapLiteral = <int, String>{0: 'foo'};
+const listConcatenation = <int>[...listLiteral];
+const setConcatenation = <int>{...setLiteral};
+const mapConcatenation = <int, String>{...mapLiteral};
+const objectTypeLiteralIdentical =
+ identical(objectTypeLiteral, lib.objectTypeLiteral);
+const partialInstantiationIdentical =
+ identical(partialInstantiation, lib.partialInstantiation);
+const instanceIdentical = identical(instance, lib.instance);
+const functionTypeLiteralIdentical =
+ identical(functionTypeLiteral, lib.functionTypeLiteral);
+const genericFunctionTypeLiteralIdentical =
+ identical(genericFunctionTypeLiteral, lib.genericFunctionTypeLiteral);
+const listLiteralIdentical = identical(listLiteral, lib.listLiteral);
+const setLiteralIdentical = identical(setLiteral, lib.setLiteral);
+const mapLiteralIdentical = identical(mapLiteral, lib.mapLiteral);
+const listConcatenationIdentical =
+ identical(listConcatenation, lib.listConcatenation);
+const setConcatenationIdentical =
+ identical(setConcatenation, lib.setConcatenation);
+const mapConcatenationIdentical =
+ identical(mapConcatenation, lib.mapConcatenation);
+final bool inStrongMode = _inStrongMode();
+bool _inStrongMode() {}
+main() {}
+test(expected, actual) {}
diff --git a/pkg/front_end/testcases/nnbd/constants.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/constants.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..03b68b2
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/constants.dart.textual_outline_modelled.expect
@@ -0,0 +1,37 @@
+import 'constants_lib.dart' as lib;
+
+bool _inStrongMode() {}
+const functionTypeLiteral = F1;
+const functionTypeLiteralIdentical =
+ identical(functionTypeLiteral, lib.functionTypeLiteral);
+const genericFunctionTypeLiteral = F2;
+const genericFunctionTypeLiteralIdentical =
+ identical(genericFunctionTypeLiteral, lib.genericFunctionTypeLiteral);
+const instance = const lib.Class<int>(0);
+const instanceIdentical = identical(instance, lib.instance);
+const int Function(int) partialInstantiation = lib.id;
+const listConcatenation = <int>[...listLiteral];
+const listConcatenationIdentical =
+ identical(listConcatenation, lib.listConcatenation);
+const listLiteral = <int>[0];
+const listLiteralIdentical = identical(listLiteral, lib.listLiteral);
+const mapConcatenation = <int, String>{...mapLiteral};
+const mapConcatenationIdentical =
+ identical(mapConcatenation, lib.mapConcatenation);
+const mapLiteral = <int, String>{0: 'foo'};
+const mapLiteralIdentical = identical(mapLiteral, lib.mapLiteral);
+const objectTypeLiteral = Object;
+const objectTypeLiteralIdentical =
+ identical(objectTypeLiteral, lib.objectTypeLiteral);
+const partialInstantiationIdentical =
+ identical(partialInstantiation, lib.partialInstantiation);
+const setConcatenation = <int>{...setLiteral};
+const setConcatenationIdentical =
+ identical(setConcatenation, lib.setConcatenation);
+const setLiteral = <int>{0};
+const setLiteralIdentical = identical(setLiteral, lib.setLiteral);
+final bool inStrongMode = _inStrongMode();
+main() {}
+test(expected, actual) {}
+typedef F1<T> = T Function(T);
+typedef F2 = T Function<T>(T);
diff --git a/pkg/front_end/testcases/nnbd/covariant_equals.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/covariant_equals.dart.textual_outline.expect
new file mode 100644
index 0000000..adc9984
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/covariant_equals.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+class A {
+ bool operator ==(covariant A other) => true;
+}
+
+class B extends A {
+ bool operator ==(other) => true;
+}
+
+class C<T> {
+ bool operator ==(covariant C<T> other) => true;
+}
+
+class D extends C<int> {}
+
+main() {}
+testNonNullable(A a, B b, C c_dynamic, C<int> c_int, C<String> c_string, D d) {}
+testNullable(
+ A? a, B? b, C? c_dynamic, C<int>? c_int, C<String>? c_string, D? d) {}
diff --git a/pkg/front_end/testcases/nnbd/covariant_equals.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/covariant_equals.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..adc9984
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/covariant_equals.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+class A {
+ bool operator ==(covariant A other) => true;
+}
+
+class B extends A {
+ bool operator ==(other) => true;
+}
+
+class C<T> {
+ bool operator ==(covariant C<T> other) => true;
+}
+
+class D extends C<int> {}
+
+main() {}
+testNonNullable(A a, B b, C c_dynamic, C<int> c_int, C<String> c_string, D d) {}
+testNullable(
+ A? a, B? b, C? c_dynamic, C<int>? c_int, C<String>? c_string, D? d) {}
diff --git a/pkg/front_end/testcases/nnbd/covariant_nnbd_top_merge.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/covariant_nnbd_top_merge.dart.textual_outline.expect
new file mode 100644
index 0000000..7e4bc1e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/covariant_nnbd_top_merge.dart.textual_outline.expect
@@ -0,0 +1,35 @@
+abstract class A {
+ void method(dynamic a);
+}
+
+abstract class B {
+ void method(covariant num a);
+}
+
+abstract class C {
+ void method(covariant int a);
+}
+
+abstract class D1 implements A, B, C {}
+
+abstract class D2 implements A, B {}
+
+abstract class D3 implements B, C {}
+
+abstract class D4 implements C, B {}
+
+abstract class D5 implements A, C {}
+
+abstract class E {
+ void method(num a);
+}
+
+abstract class F {
+ void method(covariant int a);
+}
+
+abstract class G1 implements E, F {}
+
+abstract class G2 implements F, E {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/covariant_nnbd_top_merge.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/covariant_nnbd_top_merge.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7e4bc1e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/covariant_nnbd_top_merge.dart.textual_outline_modelled.expect
@@ -0,0 +1,35 @@
+abstract class A {
+ void method(dynamic a);
+}
+
+abstract class B {
+ void method(covariant num a);
+}
+
+abstract class C {
+ void method(covariant int a);
+}
+
+abstract class D1 implements A, B, C {}
+
+abstract class D2 implements A, B {}
+
+abstract class D3 implements B, C {}
+
+abstract class D4 implements C, B {}
+
+abstract class D5 implements A, C {}
+
+abstract class E {
+ void method(num a);
+}
+
+abstract class F {
+ void method(covariant int a);
+}
+
+abstract class G1 implements E, F {}
+
+abstract class G2 implements F, E {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/definite_assignment_and_completion.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/definite_assignment_and_completion.dart.textual_outline.expect
new file mode 100644
index 0000000..5f6d991
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/definite_assignment_and_completion.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+int foo() {}
+int bar() => 0;
+int baz(int x) {}
+int boz(int x) => x;
+
+class Class {
+ final int x;
+ const Class(int x) : this.x = x;
+ int foo() {}
+ int bar() => 0;
+ int baz(int x) {}
+ int boz(int x) => x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/definite_assignment_and_completion.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/definite_assignment_and_completion.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..84320f1
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/definite_assignment_and_completion.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+class Class {
+ const Class(int x) : this.x = x;
+ final int x;
+ int bar() => 0;
+ int baz(int x) {}
+ int boz(int x) => x;
+ int foo() {}
+}
+
+int bar() => 0;
+int baz(int x) {}
+int boz(int x) => x;
+int foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/definitely_assigned.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/definitely_assigned.dart.textual_outline.expect
new file mode 100644
index 0000000..1932ec0
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/definitely_assigned.dart.textual_outline.expect
@@ -0,0 +1,45 @@
+import 'dart:async';
+
+methodDirect<T>(T value) {}
+var fieldDirect = <T>(T value) {
+ late;
+ final T local2;
+ late;
+ final int local4;
+ late;
+ final FutureOr<int> local6;
+ local2 = value;
+ local4 = 0;
+ local6 = 0;
+ local2 = value;
+ local4 = 0;
+ local6 = 0;
+};
+methodConditional<T>(bool b, T value) {}
+var fieldConditional = <T>(bool b, T value) {
+ late;
+ final T local2;
+ late;
+ final int local4;
+ late;
+ final FutureOr<int> local6;
+ if (b) {
+ local2 = value;
+ local4 = 0;
+ local6 = 0;
+ }
+ local2 = value;
+ local4 = 0;
+ local6 = 0;
+ local2 = value;
+ local4 = 0;
+ local6 = 0;
+};
+methodCompound() {}
+var fieldCompound = () {
+ late;
+ final int local4;
+ local4 = 0;
+ local4 += 0;
+};
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/definitely_assigned.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/definitely_assigned.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..be04eb0
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/definitely_assigned.dart.textual_outline_modelled.expect
@@ -0,0 +1,45 @@
+import 'dart:async';
+
+main() {}
+methodCompound() {}
+methodConditional<T>(bool b, T value) {}
+methodDirect<T>(T value) {}
+var fieldCompound = () {
+ late;
+ final int local4;
+ local4 = 0;
+ local4 += 0;
+};
+var fieldConditional = <T>(bool b, T value) {
+ late;
+ final T local2;
+ late;
+ final int local4;
+ late;
+ final FutureOr<int> local6;
+ if (b) {
+ local2 = value;
+ local4 = 0;
+ local6 = 0;
+ }
+ local2 = value;
+ local4 = 0;
+ local6 = 0;
+ local2 = value;
+ local4 = 0;
+ local6 = 0;
+};
+var fieldDirect = <T>(T value) {
+ late;
+ final T local2;
+ late;
+ final int local4;
+ late;
+ final FutureOr<int> local6;
+ local2 = value;
+ local4 = 0;
+ local6 = 0;
+ local2 = value;
+ local4 = 0;
+ local6 = 0;
+};
diff --git a/pkg/front_end/testcases/nnbd/definitely_unassigned.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/definitely_unassigned.dart.textual_outline.expect
new file mode 100644
index 0000000..f27c6c0
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/definitely_unassigned.dart.textual_outline.expect
@@ -0,0 +1,64 @@
+import 'dart:async';
+
+methodDirect<T>(T value) {}
+var fieldDirect = <T>(T value) {
+ T local1;
+ late T;
+ local2;
+ int local3;
+ late int;
+ local4;
+ FutureOr<int> local5;
+ late FutureOr;
+ <int>[];
+ local6;
+ late T;
+ local7 = value;
+ local1;
+ local2;
+ local3;
+ local4;
+ local5;
+ local6;
+ local7;
+};
+methodConditional<T>(bool b, T value) {}
+var fieldConditional = <T>(bool b, T value) {
+ T local1;
+ late T;
+ local2;
+ int local3;
+ late int;
+ local4;
+ FutureOr<int> local5;
+ late FutureOr;
+ <int>[];
+ local6;
+ late T;
+ local7 = value;
+ if (b) {
+ local1 = value;
+ local2 = value;
+ local3 = 0;
+ local4 = 0;
+ local5 = 0;
+ local6 = 0;
+ local7;
+ }
+ local1;
+ local2;
+ local3;
+ local4;
+ local5;
+ local6;
+ local7;
+};
+methodCompound() {}
+var fieldCompound = () {
+ int local3;
+ late int;
+ local4;
+ local3 += 0;
+ local4 += 0;
+};
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/definitely_unassigned.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/definitely_unassigned.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..46a4371
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/definitely_unassigned.dart.textual_outline_modelled.expect
@@ -0,0 +1,64 @@
+import 'dart:async';
+
+main() {}
+methodCompound() {}
+methodConditional<T>(bool b, T value) {}
+methodDirect<T>(T value) {}
+var fieldCompound = () {
+ int local3;
+ late int;
+ local4;
+ local3 += 0;
+ local4 += 0;
+};
+var fieldConditional = <T>(bool b, T value) {
+ T local1;
+ late T;
+ local2;
+ int local3;
+ late int;
+ local4;
+ FutureOr<int> local5;
+ late FutureOr;
+ <int>[];
+ local6;
+ late T;
+ local7 = value;
+ if (b) {
+ local1 = value;
+ local2 = value;
+ local3 = 0;
+ local4 = 0;
+ local5 = 0;
+ local6 = 0;
+ local7;
+ }
+ local1;
+ local2;
+ local3;
+ local4;
+ local5;
+ local6;
+ local7;
+};
+var fieldDirect = <T>(T value) {
+ T local1;
+ late T;
+ local2;
+ int local3;
+ late int;
+ local4;
+ FutureOr<int> local5;
+ late FutureOr;
+ <int>[];
+ local6;
+ late T;
+ local7 = value;
+ local1;
+ local2;
+ local3;
+ local4;
+ local5;
+ local6;
+ local7;
+};
diff --git a/pkg/front_end/testcases/nnbd/definitely_unassigned_late_local_variables.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/definitely_unassigned_late_local_variables.dart.textual_outline.expect
new file mode 100644
index 0000000..fe91737
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/definitely_unassigned_late_local_variables.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+abstract class A<T> {
+ bar(T value) {}
+ barInt(int value) {}
+ foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/definitely_unassigned_late_local_variables.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/definitely_unassigned_late_local_variables.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fe91737
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/definitely_unassigned_late_local_variables.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+abstract class A<T> {
+ bar(T value) {}
+ barInt(int value) {}
+ foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/demote_closure_types.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/demote_closure_types.dart.textual_outline.expect
new file mode 100644
index 0000000..fee39b9
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/demote_closure_types.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+method<T>(T a, T b) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/demote_closure_types.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/demote_closure_types.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..caff637
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/demote_closure_types.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+main() {}
+method<T>(T a, T b) {}
diff --git a/pkg/front_end/testcases/nnbd/export_from_opt_out.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/export_from_opt_out.dart.textual_outline.expect
new file mode 100644
index 0000000..24a177d
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/export_from_opt_out.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+export 'export_from_opt_out_lib1.dart';
+export 'export_from_opt_out_lib2.dart' hide legacyMethod2;
+export 'export_from_opt_out_lib3.dart' show LegacyClass2;
+export 'export_from_opt_out_lib3.dart' show legacyMethod1;
+export 'export_from_opt_out_lib3.dart' show LegacyExtension;
+export 'export_from_opt_out_lib3.dart' show LegacyTypedef;
+export 'export_from_opt_out_lib3.dart' show NnbdClass1;
+export 'export_from_opt_out_lib3.dart'
+ hide LegacyClass2, LegacyExtension, LegacyTypedef, legacyMethod1;
+export 'export_from_opt_out_lib4.dart';
+export 'export_from_opt_out_lib5.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/export_from_opt_out.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/export_from_opt_out.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..24a177d
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/export_from_opt_out.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+export 'export_from_opt_out_lib1.dart';
+export 'export_from_opt_out_lib2.dart' hide legacyMethod2;
+export 'export_from_opt_out_lib3.dart' show LegacyClass2;
+export 'export_from_opt_out_lib3.dart' show legacyMethod1;
+export 'export_from_opt_out_lib3.dart' show LegacyExtension;
+export 'export_from_opt_out_lib3.dart' show LegacyTypedef;
+export 'export_from_opt_out_lib3.dart' show NnbdClass1;
+export 'export_from_opt_out_lib3.dart'
+ hide LegacyClass2, LegacyExtension, LegacyTypedef, legacyMethod1;
+export 'export_from_opt_out_lib4.dart';
+export 'export_from_opt_out_lib5.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/forbidden_supers.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/forbidden_supers.dart.textual_outline.expect
new file mode 100644
index 0000000..7b4b277
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/forbidden_supers.dart.textual_outline.expect
@@ -0,0 +1,40 @@
+class Aoo {
+}
+class Boo {
+}
+class Coo extends Boo with Aoo? {
+}
+class Doo extends Aoo? {
+}
+class Eoo implements Boo? {
+}
+class Foo extends Boo? with Aoo {
+}
+class Goo = Boo? with Aoo?;
+class Hoo extends Object with Aoo implements Boo? {
+}
+class Ioo = Object with Aoo implements Boo?;
+class Joo extends Boo with Never {
+}
+class Koo extends Never {
+}
+class Loo implements Never {
+}
+mixin Moo1 on Aoo? implements Boo? {
+}
+mixin Moo2 on Aoo?, Boo? {
+}
+mixin Moo3 implements Aoo?, Boo? {
+}
+mixin Moo4 on Aoo implements Never {
+}
+mixin Moo5 on Aoo, Never {
+}
+mixin Moo6 on Never {
+}
+mixin Moo7 implements Aoo, Never {
+}
+mixin Moo8 implements Never {
+}
+class Noo = Never with Aoo; class NooDynamic = dynamic with Aoo; class NooVoid = void with Aoo; class Ooo = Aoo with Never;
+main() { }
diff --git a/pkg/front_end/testcases/nnbd/forin.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/forin.dart.textual_outline.expect
new file mode 100644
index 0000000..1456cad
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/forin.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+error(Iterable<int>? i2, List<int>? l2, Object o1, Object? o2) {}
+ok(Iterable<int> i1, List<int> l1, dynamic d) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/forin.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/forin.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8e81031
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/forin.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+error(Iterable<int>? i2, List<int>? l2, Object o1, Object? o2) {}
+main() {}
+ok(Iterable<int> i1, List<int> l1, dynamic d) {}
diff --git a/pkg/front_end/testcases/nnbd/from_agnostic/from_agnostic.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/from_agnostic/from_agnostic.dart.textual_outline.expect
new file mode 100644
index 0000000..9d9786f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/from_agnostic/from_agnostic.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+import 'from_agnostic_lib.dart';
+
+const c1 = identical(a, b);
+const c2 = {a: 0, b: 1};
+const c3 = {a, b};
+const c4 = a;
+const c5 = b;
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/from_agnostic/from_agnostic.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/from_agnostic/from_agnostic.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9d9786f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/from_agnostic/from_agnostic.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+import 'from_agnostic_lib.dart';
+
+const c1 = identical(a, b);
+const c2 = {a: 0, b: 1};
+const c3 = {a, b};
+const c4 = a;
+const c5 = b;
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/function_types.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/function_types.dart.textual_outline.expect
new file mode 100644
index 0000000..1f61005
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/function_types.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+typedef F = void Function();
+void foo() {}
+F bar() => foo;
+F? baz() => foo;
+void Function() hest() => foo;
+void Function()? fisk() => foo;
+Function()? foobar(Function()? x) => null;
+
+class A<T> {}
+
+class B extends A<Function()?> {
+ Function()? method(Function()? x) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/function_types.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/function_types.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8a2c7a1
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/function_types.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+F bar() => foo;
+F? baz() => foo;
+Function()? foobar(Function()? x) => null;
+
+class A<T> {}
+
+class B extends A<Function()?> {
+ Function()? method(Function()? x) => null;
+}
+
+main() {}
+typedef F = void Function();
+void Function() hest() => foo;
+void Function()? fisk() => foo;
+void foo() {}
diff --git a/pkg/front_end/testcases/nnbd/future_or_variables.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/future_or_variables.dart.textual_outline.expect
new file mode 100644
index 0000000..a1e748f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/future_or_variables.dart.textual_outline.expect
@@ -0,0 +1,49 @@
+import 'dart:async';
+
+FutureOr topLevelField1;
+FutureOr<int?> topLevelField2;
+FutureOr<FutureOr> topLevelField3;
+void toplevelMethod1(
+ [FutureOr parameter1,
+ FutureOr<int?> parameter2,
+ FutureOr<FutureOr> parameter3]) {}
+void toplevelMethod2(
+ {FutureOr parameter1,
+ FutureOr<int?> parameter2,
+ FutureOr<FutureOr> parameter3}) {}
+
+class Class1 {
+ FutureOr instanceField1;
+ FutureOr<int?> instanceField2;
+ FutureOr<FutureOr> instanceField3;
+ static FutureOr staticField1;
+ static FutureOr<int?> staticField2;
+ static FutureOr<FutureOr> staticField3;
+ void instanceMethod1(
+ [FutureOr parameter1,
+ FutureOr<int?> parameter2,
+ FutureOr<FutureOr> parameter3]) {}
+ void instanceMethod2(
+ {FutureOr parameter1,
+ FutureOr<int?> parameter2,
+ FutureOr<FutureOr> parameter3}) {}
+ static void staticMethod1(
+ [FutureOr parameter1,
+ FutureOr<int?> parameter2,
+ FutureOr<FutureOr> parameter3]) {}
+ static void staticMethod2(
+ {FutureOr parameter1,
+ FutureOr<int?> parameter2,
+ FutureOr<FutureOr> parameter3}) {}
+}
+
+class Class2 {
+ FutureOr instanceField1;
+ FutureOr<int?> instanceField2;
+ FutureOr<FutureOr> instanceField3;
+ Class2.constructor1(
+ this.instanceField1, this.instanceField2, this.instanceField3);
+ Class2.constructor2();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/future_or_variables.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/future_or_variables.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ff98b1c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/future_or_variables.dart.textual_outline_modelled.expect
@@ -0,0 +1,49 @@
+import 'dart:async';
+
+FutureOr topLevelField1;
+FutureOr<FutureOr> topLevelField3;
+FutureOr<int?> topLevelField2;
+
+class Class1 {
+ FutureOr instanceField1;
+ FutureOr<FutureOr> instanceField3;
+ FutureOr<int?> instanceField2;
+ static FutureOr staticField1;
+ static FutureOr<FutureOr> staticField3;
+ static FutureOr<int?> staticField2;
+ static void staticMethod1(
+ [FutureOr parameter1,
+ FutureOr<int?> parameter2,
+ FutureOr<FutureOr> parameter3]) {}
+ static void staticMethod2(
+ {FutureOr parameter1,
+ FutureOr<int?> parameter2,
+ FutureOr<FutureOr> parameter3}) {}
+ void instanceMethod1(
+ [FutureOr parameter1,
+ FutureOr<int?> parameter2,
+ FutureOr<FutureOr> parameter3]) {}
+ void instanceMethod2(
+ {FutureOr parameter1,
+ FutureOr<int?> parameter2,
+ FutureOr<FutureOr> parameter3}) {}
+}
+
+class Class2 {
+ Class2.constructor1(
+ this.instanceField1, this.instanceField2, this.instanceField3);
+ Class2.constructor2();
+ FutureOr instanceField1;
+ FutureOr<FutureOr> instanceField3;
+ FutureOr<int?> instanceField2;
+}
+
+main() {}
+void toplevelMethod1(
+ [FutureOr parameter1,
+ FutureOr<int?> parameter2,
+ FutureOr<FutureOr> parameter3]) {}
+void toplevelMethod2(
+ {FutureOr parameter1,
+ FutureOr<int?> parameter2,
+ FutureOr<FutureOr> parameter3}) {}
diff --git a/pkg/front_end/testcases/nnbd/generic_override.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/generic_override.dart.textual_outline.expect
new file mode 100644
index 0000000..fc94cdb
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/generic_override.dart.textual_outline.expect
@@ -0,0 +1,57 @@
+import 'generic_override_lib.dart';
+
+abstract class Class1 {
+ void method1a<T>();
+ void method1b<T>();
+ void method1c<T>();
+ void method2a<T extends Object?>();
+ void method2b<T extends Object?>();
+ void method2c<T extends Object?>();
+ void method3a<T extends dynamic>();
+ void method3b<T extends dynamic>();
+ void method3c<T extends dynamic>();
+ void method4a<T extends Object>();
+ void method4b<T extends Object>();
+ void method4c<T extends Object?>();
+ void method5a<T extends Class1>();
+ void method5b<T extends Class1>();
+ void method5c<T extends Class1?>();
+}
+
+abstract class Class2 extends Class1 {
+ void method1a<T>();
+ void method1b<T extends Object?>();
+ void method1c<T extends dynamic>();
+ void method2a<T>();
+ void method2b<T extends Object?>();
+ void method2c<T extends dynamic>();
+ void method3a<T>();
+ void method3b<T extends Object?>();
+ void method3c<T extends dynamic>();
+ void method4a<T extends Object>();
+ void method4b<T extends Object?>();
+ void method4c<T extends Object>();
+ void method5a<T extends Class1>();
+ void method5b<T extends Class1?>();
+ void method5c<T extends Class1>();
+}
+
+abstract class Class3 extends LegacyClass1 {
+ void method1a<T>();
+ void method1b<T extends Object?>();
+ void method1c<T extends dynamic>();
+ void method2a<T>();
+ void method2b<T extends Object?>();
+ void method2c<T extends dynamic>();
+ void method3a<T>();
+ void method3b<T extends Object?>();
+ void method3c<T extends dynamic>();
+ void method4a<T extends Object>();
+ void method4b<T extends Object?>();
+ void method4c<T extends Object>();
+ void method5a<T extends Class1>();
+ void method5b<T extends Class1?>();
+ void method5c<T extends Class1>();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/generic_override.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/generic_override.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fc94cdb
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/generic_override.dart.textual_outline_modelled.expect
@@ -0,0 +1,57 @@
+import 'generic_override_lib.dart';
+
+abstract class Class1 {
+ void method1a<T>();
+ void method1b<T>();
+ void method1c<T>();
+ void method2a<T extends Object?>();
+ void method2b<T extends Object?>();
+ void method2c<T extends Object?>();
+ void method3a<T extends dynamic>();
+ void method3b<T extends dynamic>();
+ void method3c<T extends dynamic>();
+ void method4a<T extends Object>();
+ void method4b<T extends Object>();
+ void method4c<T extends Object?>();
+ void method5a<T extends Class1>();
+ void method5b<T extends Class1>();
+ void method5c<T extends Class1?>();
+}
+
+abstract class Class2 extends Class1 {
+ void method1a<T>();
+ void method1b<T extends Object?>();
+ void method1c<T extends dynamic>();
+ void method2a<T>();
+ void method2b<T extends Object?>();
+ void method2c<T extends dynamic>();
+ void method3a<T>();
+ void method3b<T extends Object?>();
+ void method3c<T extends dynamic>();
+ void method4a<T extends Object>();
+ void method4b<T extends Object?>();
+ void method4c<T extends Object>();
+ void method5a<T extends Class1>();
+ void method5b<T extends Class1?>();
+ void method5c<T extends Class1>();
+}
+
+abstract class Class3 extends LegacyClass1 {
+ void method1a<T>();
+ void method1b<T extends Object?>();
+ void method1c<T extends dynamic>();
+ void method2a<T>();
+ void method2b<T extends Object?>();
+ void method2c<T extends dynamic>();
+ void method3a<T>();
+ void method3b<T extends Object?>();
+ void method3c<T extends dynamic>();
+ void method4a<T extends Object>();
+ void method4b<T extends Object?>();
+ void method4c<T extends Object>();
+ void method5a<T extends Class1>();
+ void method5b<T extends Class1?>();
+ void method5c<T extends Class1>();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/infer_constraints_from_opt_in.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/infer_constraints_from_opt_in.dart.textual_outline.expect
new file mode 100644
index 0000000..1c32596
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/infer_constraints_from_opt_in.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+// @dart = 2.5
+import 'infer_constraints_from_opt_in_lib.dart';
+
+main() {}
+
+abstract class A {
+ baz(B b) {}
+}
diff --git a/pkg/front_end/testcases/nnbd/infer_constraints_from_opt_in.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/infer_constraints_from_opt_in.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d34fee7
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/infer_constraints_from_opt_in.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+// @dart = 2.5
+import 'infer_constraints_from_opt_in_lib.dart';
+
+abstract class A {
+ baz(B b) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/infer_from_late_variable.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/infer_from_late_variable.dart.textual_outline.expect
new file mode 100644
index 0000000..0ce51c7
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/infer_from_late_variable.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+T f<T>(T t) => t;
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/infer_from_late_variable.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/infer_from_late_variable.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0ce51c7
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/infer_from_late_variable.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+T f<T>(T t) => t;
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/infer_from_opt_in.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/infer_from_opt_in.dart.textual_outline.expect
new file mode 100644
index 0000000..b42d5fa
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/infer_from_opt_in.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'infer_from_opt_in_lib.dart';
+
+reify<T>(T arg) => T;
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/infer_from_opt_in.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/infer_from_opt_in.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0c543e4
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/infer_from_opt_in.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'infer_from_opt_in_lib.dart';
+
+main() {}
+reify<T>(T arg) => T;
diff --git a/pkg/front_end/testcases/nnbd/infer_from_opt_out.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/infer_from_opt_out.dart.textual_outline.expect
new file mode 100644
index 0000000..a8d0a04
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/infer_from_opt_out.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'infer_from_opt_out_lib.dart';
+
+reify<T>(T arg) => T;
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/infer_from_opt_out.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/infer_from_opt_out.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3ba5457
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/infer_from_opt_out.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'infer_from_opt_out_lib.dart';
+
+main() {}
+reify<T>(T arg) => T;
diff --git a/pkg/front_end/testcases/nnbd/infer_if_null.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/infer_if_null.dart.textual_outline.expect
new file mode 100644
index 0000000..bd0c406
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/infer_if_null.dart.textual_outline.expect
@@ -0,0 +1,24 @@
+T hest1<T>() => throw "hest";
+test1() { }
+class A2 {
+ String? foo;
+}
+test2(A2 a) { }
+test3() { }
+test4() { }
+class A5 {
+ void operator []=(int index, String? value) { }
+ String? operator [](int index) => null;
+}
+class B5 extends A5 {
+ test5() { }
+}
+extension E6 ;
+on double (){ }
+test6() { }
+class A7 {
+ String foo = "foo";
+ String? bar;
+}
+test7(A7? a) { }
+main() { }
diff --git a/pkg/front_end/testcases/nnbd/infer_in_legacy_from_opted_in.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/infer_in_legacy_from_opted_in.dart.textual_outline.expect
new file mode 100644
index 0000000..40f74b8
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/infer_in_legacy_from_opted_in.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import './infer_in_legacy_from_opted_in_lib.dart';
+
+bar(int x) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/infer_in_legacy_from_opted_in.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/infer_in_legacy_from_opted_in.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..40f74b8
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/infer_in_legacy_from_opted_in.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+// @dart = 2.6
+import './infer_in_legacy_from_opted_in_lib.dart';
+
+bar(int x) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/infer_method_types.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/infer_method_types.dart.textual_outline.expect
new file mode 100644
index 0000000..316cf4c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/infer_method_types.dart.textual_outline.expect
@@ -0,0 +1,45 @@
+abstract class A {
+ Object? m(covariant int a);
+}
+
+abstract class B {
+ dynamic m(covariant num a);
+}
+
+abstract class C {
+ void m(num a);
+}
+
+abstract class D implements A {
+ Object? m(int a);
+}
+
+abstract class E implements B {
+ dynamic m(num a);
+}
+
+abstract class F {
+ Object? m(int a);
+}
+
+abstract class G implements C {
+ m(a);
+}
+
+abstract class H implements D, E, F, C {}
+
+abstract class I implements D {
+ m(a);
+}
+
+abstract class J implements H {
+ m(a);
+}
+
+abstract class K implements I, E, G {}
+
+abstract class L implements K {
+ m(a);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/infer_method_types.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/infer_method_types.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..316cf4c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/infer_method_types.dart.textual_outline_modelled.expect
@@ -0,0 +1,45 @@
+abstract class A {
+ Object? m(covariant int a);
+}
+
+abstract class B {
+ dynamic m(covariant num a);
+}
+
+abstract class C {
+ void m(num a);
+}
+
+abstract class D implements A {
+ Object? m(int a);
+}
+
+abstract class E implements B {
+ dynamic m(num a);
+}
+
+abstract class F {
+ Object? m(int a);
+}
+
+abstract class G implements C {
+ m(a);
+}
+
+abstract class H implements D, E, F, C {}
+
+abstract class I implements D {
+ m(a);
+}
+
+abstract class J implements H {
+ m(a);
+}
+
+abstract class K implements I, E, G {}
+
+abstract class L implements K {
+ m(a);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/inheritance_from_opt_in.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/inheritance_from_opt_in.dart.textual_outline.expect
new file mode 100644
index 0000000..01cba4e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/inheritance_from_opt_in.dart.textual_outline.expect
@@ -0,0 +1,26 @@
+// @dart = 2.5
+import 'inheritance_from_opt_in_lib.dart';
+class LegacyClass1 extends Class1 {
+}
+class LegacyClass2<T> extends Class2<T> {
+}
+class LegacyClass3a<T> extends Class3<T> {
+}
+class LegacyClass3b<T> extends Class3<T> implements GenericInterface<T> {
+}
+class LegacyClass4a extends Class4a {
+}
+class LegacyClass4b implements GenericInterface<num> {
+}
+class LegacyClass4c implements GenericInterface<num?> {
+}
+class LegacyClass4d extends Class4a implements GenericInterface<num> {
+}
+class LegacyClass4e implements Class4a, Class4b {
+}
+class LegacyClass5 extends Class5 implements GenericInterface<Object> {
+}
+class LegacyClass6a<T> extends Class3<T> implements GenericSubInterface<T> {
+}
+class LegacyClass6b<T> extends LegacyClass3a<T> implements GenericSubInterface<T> {
+}
diff --git a/pkg/front_end/testcases/nnbd/inheritance_from_opt_in.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/inheritance_from_opt_in.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e42e9ac
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/inheritance_from_opt_in.dart.textual_outline_modelled.expect
@@ -0,0 +1,27 @@
+// @dart = 2.5
+import 'inheritance_from_opt_in_lib.dart';
+
+class LegacyClass1 extends Class1 {}
+
+class LegacyClass2<T> extends Class2<T> {}
+
+class LegacyClass3a<T> extends Class3<T> {}
+
+class LegacyClass3b<T> extends Class3<T> implements GenericInterface<T> {}
+
+class LegacyClass4a extends Class4a {}
+
+class LegacyClass4b implements GenericInterface<num> {}
+
+class LegacyClass4c implements GenericInterface<num?> {}
+
+class LegacyClass4d extends Class4a implements GenericInterface<num> {}
+
+class LegacyClass4e implements Class4a, Class4b {}
+
+class LegacyClass5 extends Class5 implements GenericInterface<Object> {}
+
+class LegacyClass6a<T> extends Class3<T> implements GenericSubInterface<T> {}
+
+class LegacyClass6b<T> extends LegacyClass3a<T>
+ implements GenericSubInterface<T> {}
diff --git a/pkg/front_end/testcases/nnbd/inheritance_from_opt_out.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/inheritance_from_opt_out.dart.textual_outline.expect
new file mode 100644
index 0000000..dfb4c65
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/inheritance_from_opt_out.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+import 'inheritance_from_opt_out_lib.dart';
+
+class Class1 extends LegacyClass1 {}
+
+class Class2<T> extends LegacyClass2<T> {}
+
+class Class3a<T> extends LegacyClass3<T> {}
+
+class Class3b<T> extends LegacyClass3<T> implements GenericInterface<T> {}
+
+class Class4a extends LegacyClass4 {}
+
+class Class4b implements GenericInterface<num> {}
+
+class Class4c implements GenericInterface<num?> {}
+
+class Class4d extends LegacyClass4 implements GenericInterface<num> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/inheritance_from_opt_out.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/inheritance_from_opt_out.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..dfb4c65
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/inheritance_from_opt_out.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+import 'inheritance_from_opt_out_lib.dart';
+
+class Class1 extends LegacyClass1 {}
+
+class Class2<T> extends LegacyClass2<T> {}
+
+class Class3a<T> extends LegacyClass3<T> {}
+
+class Class3b<T> extends LegacyClass3<T> implements GenericInterface<T> {}
+
+class Class4a extends LegacyClass4 {}
+
+class Class4b implements GenericInterface<num> {}
+
+class Class4c implements GenericInterface<num?> {}
+
+class Class4d extends LegacyClass4 implements GenericInterface<num> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/injected_late_field_checks/main.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/injected_late_field_checks/main.dart.textual_outline.expect
new file mode 100644
index 0000000..3c9c90e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/injected_late_field_checks/main.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+import 'dart:test';
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/injected_late_field_checks/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/injected_late_field_checks/main.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3c9c90e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/injected_late_field_checks/main.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+import 'dart:test';
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/intersection_types.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/intersection_types.dart.textual_outline.expect
new file mode 100644
index 0000000..ad879ef
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/intersection_types.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+class A {}
+
+class B extends A {}
+
+class C extends B {}
+
+class Foo<T extends A?> {
+ doPromotionsToNullable(T t) {}
+ doPromotionsToNonNullable(T t) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/intersection_types.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/intersection_types.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5a6a42a
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/intersection_types.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+class A {}
+
+class B extends A {}
+
+class C extends B {}
+
+class Foo<T extends A?> {
+ doPromotionsToNonNullable(T t) {}
+ doPromotionsToNullable(T t) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue39659.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue39659.dart.textual_outline.expect
new file mode 100644
index 0000000..fa47f13
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue39659.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+foo() {}
+String? bar() => "asdf";
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue39659.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue39659.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4df9bca
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue39659.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+String? bar() => "asdf";
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue39822.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue39822.dart.textual_outline.expect
new file mode 100644
index 0000000..e73ad63
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue39822.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+foo(Null x) {}
+bar(int y) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue39822.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue39822.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0e94881
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue39822.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+bar(int y) {}
+foo(Null x) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue40093.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue40093.dart.textual_outline.expect
new file mode 100644
index 0000000..c7e2924
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue40093.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+error() {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue40093.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue40093.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c7e2924
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue40093.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+error() {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue40134.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue40134.dart.textual_outline.expect
new file mode 100644
index 0000000..9297f99
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue40134.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+class GenericMethodBounds<T> {
+ Type get t => T;
+ GenericMethodBounds<E> foo<E extends T>() => new GenericMethodBounds<E>();
+ GenericMethodBounds<E> bar<E extends void Function(T)>() =>
+ new GenericMethodBounds<E>();
+}
+
+class GenericMethodBoundsDerived extends GenericMethodBounds<num> {
+ GenericMethodBounds<E> foo<E extends num>() => new GenericMethodBounds<E>();
+ GenericMethodBounds<E> bar<E extends void Function(num)>() =>
+ new GenericMethodBounds<E>();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue40134.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue40134.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0f3cd4f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue40134.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+class GenericMethodBounds<T> {
+ GenericMethodBounds<E> bar<E extends void Function(T)>() =>
+ new GenericMethodBounds<E>();
+ GenericMethodBounds<E> foo<E extends T>() => new GenericMethodBounds<E>();
+ Type get t => T;
+}
+
+class GenericMethodBoundsDerived extends GenericMethodBounds<num> {
+ GenericMethodBounds<E> bar<E extends void Function(num)>() =>
+ new GenericMethodBounds<E>();
+ GenericMethodBounds<E> foo<E extends num>() => new GenericMethodBounds<E>();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue40512/issue40512.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue40512/issue40512.dart.textual_outline.expect
new file mode 100644
index 0000000..6d60882
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue40512/issue40512.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'issue40512_lib.dart';
+
+class C extends Object with A, B {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue40512/issue40512.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue40512/issue40512.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6d60882
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue40512/issue40512.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'issue40512_lib.dart';
+
+class C extends Object with A, B {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue40600.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue40600.dart.textual_outline.expect
new file mode 100644
index 0000000..e698e05
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue40600.dart.textual_outline.expect
@@ -0,0 +1,20 @@
+import 'dart:async';
+
+class B<Y> {
+ bar(FutureOr<Y> y) {}
+}
+
+class A<X> {
+ final b = new B<X>();
+ foo([FutureOr<X>? x]) {}
+}
+
+class C<T> {
+ FutureOr<T> baz<X extends FutureOr<T>>(FutureOr<T> x) => x;
+}
+
+class D<T> extends C<T> {
+ FutureOr<T> baz<X extends FutureOr<T>>(FutureOr<T> x) => x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue40600.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue40600.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..88df60c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue40600.dart.textual_outline_modelled.expect
@@ -0,0 +1,20 @@
+import 'dart:async';
+
+class A<X> {
+ final b = new B<X>();
+ foo([FutureOr<X>? x]) {}
+}
+
+class B<Y> {
+ bar(FutureOr<Y> y) {}
+}
+
+class C<T> {
+ FutureOr<T> baz<X extends FutureOr<T>>(FutureOr<T> x) => x;
+}
+
+class D<T> extends C<T> {
+ FutureOr<T> baz<X extends FutureOr<T>>(FutureOr<T> x) => x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue40601.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue40601.dart.textual_outline.expect
new file mode 100644
index 0000000..96d9d0d
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue40601.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+abstract class A<T> {
+ T baz();
+ bar(T value) {}
+ foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue40601.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue40601.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..96d9d0d
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue40601.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+abstract class A<T> {
+ T baz();
+ bar(T value) {}
+ foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue40805.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue40805.dart.textual_outline.expect
new file mode 100644
index 0000000..4c9d91e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue40805.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+main() { }
+class C {
+ covariant late ;
+ final int x;
+}
+class D extends C {
+ set x(num value) { }
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41102.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41102.dart.strong.expect
index 6c39527..cad8aa5 100644
--- a/pkg/front_end/testcases/nnbd/issue41102.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue41102.dart.strong.expect
@@ -58,7 +58,7 @@
// final s14 = (s13)();
// ^
//
-// pkg/front_end/testcases/nnbd/issue41102.dart:49:19: Error: Can't throw a value of 'Null?' since it is neither dynamic nor non-nullable.
+// pkg/front_end/testcases/nnbd/issue41102.dart:49:19: Error: Can't throw a value of 'Null' since it is neither dynamic nor non-nullable.
// final s15 = throw null;
// ^
//
@@ -120,7 +120,7 @@
Try calling using ?.call instead.
final s14 = (s13)();
^" in self::s13.call();
-static final field Never s15 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:49:19: Error: Can't throw a value of 'Null?' since it is neither dynamic nor non-nullable.
+static final field Never s15 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:49:19: Error: Can't throw a value of 'Null' since it is neither dynamic nor non-nullable.
final s15 = throw null;
^" as{TypeError,ForDynamic,ForNonNullableByDefault} Never;
static method main() → void {}
diff --git a/pkg/front_end/testcases/nnbd/issue41102.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41102.dart.strong.transformed.expect
index ae59b84..61c0af4 100644
--- a/pkg/front_end/testcases/nnbd/issue41102.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41102.dart.strong.transformed.expect
@@ -58,7 +58,7 @@
// final s14 = (s13)();
// ^
//
-// pkg/front_end/testcases/nnbd/issue41102.dart:49:19: Error: Can't throw a value of 'Null?' since it is neither dynamic nor non-nullable.
+// pkg/front_end/testcases/nnbd/issue41102.dart:49:19: Error: Can't throw a value of 'Null' since it is neither dynamic nor non-nullable.
// final s15 = throw null;
// ^
//
@@ -120,7 +120,7 @@
Try calling using ?.call instead.
final s14 = (s13)();
^" in self::s13.call();
-static final field Never s15 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:49:19: Error: Can't throw a value of 'Null?' since it is neither dynamic nor non-nullable.
+static final field Never s15 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:49:19: Error: Can't throw a value of 'Null' since it is neither dynamic nor non-nullable.
final s15 = throw null;
^" as{TypeError,ForDynamic,ForNonNullableByDefault} Never;
static method main() → void {}
diff --git a/pkg/front_end/testcases/nnbd/issue41102.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue41102.dart.textual_outline.expect
new file mode 100644
index 0000000..841a03e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41102.dart.textual_outline.expect
@@ -0,0 +1,29 @@
+import 'dart:async';
+
+void main() {}
+final t = StreamTransformer.fromHandlers(
+ handleData: (data, sink) => Future.microtask(() => sink.add(data)),
+ handleDone: (sink) => Future.microtask(() => sink.close()));
+final s1 = [];
+final s2 = s1?.length;
+final s3 = new List<int>(2);
+final s4 = () {
+ var e = 0;
+ switch (e) {
+ case 0:
+ print('fallthrough');
+ case 1:
+ case '':
+ }
+}();
+int? s5;
+final s6 = s5 + 0;
+List? s7;
+final s8 = s7[0];
+final s9 = s7[0] = 0;
+final s10 = s7.length;
+final s11 = s7.length = 0;
+final s12 = -s5;
+int Function()? s13;
+final s14 = (s13)();
+final s15 = throw null;
diff --git a/pkg/front_end/testcases/nnbd/issue41102.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue41102.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..dee803a
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41102.dart.textual_outline_modelled.expect
@@ -0,0 +1,29 @@
+import 'dart:async';
+
+List? s7;
+final s1 = [];
+final s10 = s7.length;
+final s11 = s7.length = 0;
+final s12 = -s5;
+final s14 = (s13)();
+final s15 = throw null;
+final s2 = s1?.length;
+final s3 = new List<int>(2);
+final s4 = () {
+ var e = 0;
+ switch (e) {
+ case 0:
+ print('fallthrough');
+ case 1:
+ case '':
+ }
+}();
+final s6 = s5 + 0;
+final s8 = s7[0];
+final s9 = s7[0] = 0;
+final t = StreamTransformer.fromHandlers(
+ handleData: (data, sink) => Future.microtask(() => sink.add(data)),
+ handleDone: (sink) => Future.microtask(() => sink.close()));
+int Function()? s13;
+int? s5;
+void main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41102.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41102.dart.weak.expect
index 6c39527..cad8aa5 100644
--- a/pkg/front_end/testcases/nnbd/issue41102.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue41102.dart.weak.expect
@@ -58,7 +58,7 @@
// final s14 = (s13)();
// ^
//
-// pkg/front_end/testcases/nnbd/issue41102.dart:49:19: Error: Can't throw a value of 'Null?' since it is neither dynamic nor non-nullable.
+// pkg/front_end/testcases/nnbd/issue41102.dart:49:19: Error: Can't throw a value of 'Null' since it is neither dynamic nor non-nullable.
// final s15 = throw null;
// ^
//
@@ -120,7 +120,7 @@
Try calling using ?.call instead.
final s14 = (s13)();
^" in self::s13.call();
-static final field Never s15 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:49:19: Error: Can't throw a value of 'Null?' since it is neither dynamic nor non-nullable.
+static final field Never s15 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:49:19: Error: Can't throw a value of 'Null' since it is neither dynamic nor non-nullable.
final s15 = throw null;
^" as{TypeError,ForDynamic,ForNonNullableByDefault} Never;
static method main() → void {}
diff --git a/pkg/front_end/testcases/nnbd/issue41102.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41102.dart.weak.transformed.expect
index ae59b84..61c0af4 100644
--- a/pkg/front_end/testcases/nnbd/issue41102.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41102.dart.weak.transformed.expect
@@ -58,7 +58,7 @@
// final s14 = (s13)();
// ^
//
-// pkg/front_end/testcases/nnbd/issue41102.dart:49:19: Error: Can't throw a value of 'Null?' since it is neither dynamic nor non-nullable.
+// pkg/front_end/testcases/nnbd/issue41102.dart:49:19: Error: Can't throw a value of 'Null' since it is neither dynamic nor non-nullable.
// final s15 = throw null;
// ^
//
@@ -120,7 +120,7 @@
Try calling using ?.call instead.
final s14 = (s13)();
^" in self::s13.call();
-static final field Never s15 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:49:19: Error: Can't throw a value of 'Null?' since it is neither dynamic nor non-nullable.
+static final field Never s15 = invalid-expression "pkg/front_end/testcases/nnbd/issue41102.dart:49:19: Error: Can't throw a value of 'Null' since it is neither dynamic nor non-nullable.
final s15 = throw null;
^" as{TypeError,ForDynamic,ForNonNullableByDefault} Never;
static method main() → void {}
diff --git a/pkg/front_end/testcases/nnbd/issue41103.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue41103.dart.textual_outline.expect
new file mode 100644
index 0000000..a80fd48
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41103.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+import 'dart:async';
+
+void main() {}
+final t = StreamTransformer.fromHandlers(
+ handleData: (data, sink) => Future.microtask(() => sink.add(data)),
+ handleDone: (sink) => Future.microtask(() => sink.close()));
diff --git a/pkg/front_end/testcases/nnbd/issue41103.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue41103.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..55b3256
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41103.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+import 'dart:async';
+
+final t = StreamTransformer.fromHandlers(
+ handleData: (data, sink) => Future.microtask(() => sink.add(data)),
+ handleDone: (sink) => Future.microtask(() => sink.close()));
+void main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41114.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue41114.dart.textual_outline.expect
new file mode 100644
index 0000000..386f405
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41114.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() async {}
diff --git a/pkg/front_end/testcases/nnbd/issue41114.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue41114.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..386f405
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41114.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() async {}
diff --git a/pkg/front_end/testcases/nnbd/issue41156.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue41156.dart.textual_outline.expect
new file mode 100644
index 0000000..2dcb814
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41156.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+Never throwing() => throw '';
+void main() {}
+void errors() async {}
diff --git a/pkg/front_end/testcases/nnbd/issue41156.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue41156.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bacddb3
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41156.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+Never throwing() => throw '';
+void errors() async {}
+void main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41180.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue41180.dart.textual_outline.expect
new file mode 100644
index 0000000..51c776d
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41180.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+// @dart = 2.5
+import 'issue41180_lib.dart';
+
+class D<Y> {
+ C<Y> method() => new C<Y>(() => null);
+}
+
+void main() {}
+void findKey(Map<String, dynamic> m, dynamic search) {}
diff --git a/pkg/front_end/testcases/nnbd/issue41180.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue41180.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..66718e1
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41180.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+// @dart = 2.5
+import 'issue41180_lib.dart';
+
+class D<Y> {
+ C<Y> method() => new C<Y>(() => null);
+}
+
+void findKey(Map<String, dynamic> m, dynamic search) {}
+void main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41210a/issue41210.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue41210a/issue41210.dart.textual_outline.expect
new file mode 100644
index 0000000..8cdec02
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41210a/issue41210.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'issue41210_lib1.dart';
+
+class C with A, B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41210a/issue41210.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue41210a/issue41210.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8cdec02
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41210a/issue41210.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'issue41210_lib1.dart';
+
+class C with A, B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41210b.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue41210b.dart.textual_outline.expect
new file mode 100644
index 0000000..083c54f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41210b.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'issue41210b_lib1.dart';
+
+class C with A, B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41210b.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue41210b.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..083c54f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41210b.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'issue41210b_lib1.dart';
+
+class C with A, B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41273.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue41273.dart.textual_outline.expect
new file mode 100644
index 0000000..6592fa9
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41273.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+void test(var x) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41273.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue41273.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..59b6cb1
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41273.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+main() {}
+void test(var x) {}
diff --git a/pkg/front_end/testcases/nnbd/issue41349.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue41349.dart.textual_outline.expect
new file mode 100644
index 0000000..ada5148
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41349.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+class A {
+ foo() => 23;
+}
+extension B ;
+on A;
+? { foo() => 42; bar() => 87; }
+extension C ;
+on A (){ }
+extension D ;
+on int ;
+Function(){ }
+? { int call() => 76; }
+main() { }
+testA(A? a) { }
+testFunction(int Function()? f) { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/nnbd/issue41415.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue41415.dart.textual_outline.expect
new file mode 100644
index 0000000..d2c1f3b
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41415.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+import "package:expect/expect.dart";
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41415.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue41415.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d2c1f3b
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41415.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+import "package:expect/expect.dart";
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41437a.dart b/pkg/front_end/testcases/nnbd/issue41437a.dart
new file mode 100644
index 0000000..778cd69
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41437a.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+dynamic getNull() => null;
+Future<dynamic> getFutureNull() async {
+ return null;
+}
+
+Future<bool> getFutureBool() async {
+ return true;
+}
+
+Future<bool> test1() async => await getNull(); // error
+Future<bool> test2() => getNull(); // ok
+bool test3() => getNull(); // ok
+Future<bool> test4() async => await getFutureNull(); // error
+Future<bool> test5() => getFutureNull(); // error
+Future<bool> test6() => getFutureBool(); // ok
+Future<bool> test7() async => getFutureBool(); // ok
+
+test() async {
+ Future<bool> test1() async => await getNull(); // error
+ Future<bool> test2() => getNull(); // ok
+ bool test3() => getNull(); // ok
+ Future<bool> test4() async => await getFutureNull(); // error
+ Future<bool> test5() => getFutureNull(); // error
+ Future<bool> test6() => getFutureBool(); // ok
+ Future<bool> test7() async => getFutureBool(); // ok
+
+ Future<bool> var1 = (() async => await getNull())(); // error
+ Future<bool> var2 = (() => getNull())(); // ok
+ bool var3 = (() => getNull())(); // ok
+ Future<bool> var4 = (() async => await getFutureNull())(); // error
+ Future<bool> var5 = (() => getFutureNull())(); // error
+ Future<bool> var6 = (() => getFutureBool())(); // ok
+ Future<bool> var7 = (() async => getFutureBool())(); // ok
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41437a.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue41437a.dart.outline.expect
new file mode 100644
index 0000000..7e28ffc
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41437a.dart.outline.expect
@@ -0,0 +1,29 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method getNull() → dynamic
+ ;
+static method getFutureNull() → asy::Future<dynamic>
+ ;
+static method getFutureBool() → asy::Future<core::bool>
+ ;
+static method test1() → asy::Future<core::bool>
+ ;
+static method test2() → asy::Future<core::bool>
+ ;
+static method test3() → core::bool
+ ;
+static method test4() → asy::Future<core::bool>
+ ;
+static method test5() → asy::Future<core::bool>
+ ;
+static method test6() → asy::Future<core::bool>
+ ;
+static method test7() → asy::Future<core::bool>
+ ;
+static method test() → dynamic
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/nnbd/issue41437a.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41437a.dart.strong.expect
new file mode 100644
index 0000000..9f84dd0
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41437a.dart.strong.expect
@@ -0,0 +1,134 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:14:31: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+// - 'Future' is from 'dart:async'.
+// - 'FutureOr' is from 'dart:async'.
+// Future<bool> test1() async => await getNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:17:31: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+// - 'Future' is from 'dart:async'.
+// - 'FutureOr' is from 'dart:async'.
+// Future<bool> test4() async => await getFutureNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:18:25: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+// - 'Future' is from 'dart:async'.
+// Future<bool> test5() => getFutureNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:23:33: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+// - 'Future' is from 'dart:async'.
+// - 'FutureOr' is from 'dart:async'.
+// Future<bool> test1() async => await getNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:26:33: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+// - 'Future' is from 'dart:async'.
+// - 'FutureOr' is from 'dart:async'.
+// Future<bool> test4() async => await getFutureNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:27:27: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+// - 'Future' is from 'dart:async'.
+// Future<bool> test5() => getFutureNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:31:52: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+// - 'Future' is from 'dart:async'.
+// Future<bool> var1 = (() async => await getNull())(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:34:58: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+// - 'Future' is from 'dart:async'.
+// Future<bool> var4 = (() async => await getFutureNull())(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:35:46: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+// - 'Future' is from 'dart:async'.
+// Future<bool> var5 = (() => getFutureNull())(); // error
+// ^
+//
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method getNull() → dynamic
+ return null;
+static method getFutureNull() → asy::Future<dynamic> async {
+ return null;
+}
+static method getFutureBool() → asy::Future<core::bool> async {
+ return true;
+}
+static method test1() → asy::Future<core::bool> async
+ return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:14:31: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+ - 'Future' is from 'dart:async'.
+ - 'FutureOr' is from 'dart:async'.
+Future<bool> test1() async => await getNull(); // error
+ ^" in await self::getNull() as{TypeError,ForNonNullableByDefault} asy::FutureOr<core::bool>;
+static method test2() → asy::Future<core::bool>
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
+static method test3() → core::bool
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+static method test4() → asy::Future<core::bool> async
+ return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:17:31: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+ - 'Future' is from 'dart:async'.
+ - 'FutureOr' is from 'dart:async'.
+Future<bool> test4() async => await getFutureNull(); // error
+ ^" in await self::getFutureNull() as{TypeError,ForNonNullableByDefault} asy::FutureOr<core::bool>;
+static method test5() → asy::Future<core::bool>
+ return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:18:25: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ - 'Future' is from 'dart:async'.
+Future<bool> test5() => getFutureNull(); // error
+ ^" in self::getFutureNull() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+static method test6() → asy::Future<core::bool>
+ return self::getFutureBool();
+static method test7() → asy::Future<core::bool> async
+ return self::getFutureBool();
+static method test() → dynamic async {
+ function test1() → asy::Future<core::bool> async
+ return let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:23:33: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+ - 'Future' is from 'dart:async'.
+ - 'FutureOr' is from 'dart:async'.
+ Future<bool> test1() async => await getNull(); // error
+ ^" in await self::getNull() as{TypeError,ForNonNullableByDefault} asy::FutureOr<core::bool>;
+ function test2() → asy::Future<core::bool>
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
+ function test3() → core::bool
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+ function test4() → asy::Future<core::bool> async
+ return let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:26:33: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+ - 'Future' is from 'dart:async'.
+ - 'FutureOr' is from 'dart:async'.
+ Future<bool> test4() async => await getFutureNull(); // error
+ ^" in await self::getFutureNull() as{TypeError,ForNonNullableByDefault} asy::FutureOr<core::bool>;
+ function test5() → asy::Future<core::bool>
+ return let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:27:27: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ - 'Future' is from 'dart:async'.
+ Future<bool> test5() => getFutureNull(); // error
+ ^" in self::getFutureNull() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+ function test6() → asy::Future<core::bool>
+ return self::getFutureBool();
+ function test7() → asy::Future<core::bool> async
+ return self::getFutureBool();
+ asy::Future<core::bool> var1 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:31:52: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ - 'Future' is from 'dart:async'.
+ Future<bool> var1 = (() async => await getNull())(); // error
+ ^" in (() → asy::Future<dynamic> async => await self::getNull()).call() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+ asy::Future<core::bool> var2 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
+ core::bool var3 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+ asy::Future<core::bool> var4 = let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:34:58: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ - 'Future' is from 'dart:async'.
+ Future<bool> var4 = (() async => await getFutureNull())(); // error
+ ^" in (() → asy::Future<dynamic> async => await self::getFutureNull()).call() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+ asy::Future<core::bool> var5 = let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:35:46: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ - 'Future' is from 'dart:async'.
+ Future<bool> var5 = (() => getFutureNull())(); // error
+ ^" in (() → asy::Future<dynamic> => self::getFutureNull()).call() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+ asy::Future<core::bool> var6 = (() → asy::Future<core::bool> => self::getFutureBool()).call();
+ asy::Future<core::bool> var7 = (() → asy::Future<core::bool> async => self::getFutureBool()).call();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41437a.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41437a.dart.strong.transformed.expect
new file mode 100644
index 0000000..2e9e775
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41437a.dart.strong.transformed.expect
@@ -0,0 +1,449 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:14:31: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+// - 'Future' is from 'dart:async'.
+// - 'FutureOr' is from 'dart:async'.
+// Future<bool> test1() async => await getNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:17:31: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+// - 'Future' is from 'dart:async'.
+// - 'FutureOr' is from 'dart:async'.
+// Future<bool> test4() async => await getFutureNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:18:25: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+// - 'Future' is from 'dart:async'.
+// Future<bool> test5() => getFutureNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:23:33: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+// - 'Future' is from 'dart:async'.
+// - 'FutureOr' is from 'dart:async'.
+// Future<bool> test1() async => await getNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:26:33: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+// - 'Future' is from 'dart:async'.
+// - 'FutureOr' is from 'dart:async'.
+// Future<bool> test4() async => await getFutureNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:27:27: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+// - 'Future' is from 'dart:async'.
+// Future<bool> test5() => getFutureNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:31:52: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+// - 'Future' is from 'dart:async'.
+// Future<bool> var1 = (() async => await getNull())(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:34:58: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+// - 'Future' is from 'dart:async'.
+// Future<bool> var4 = (() async => await getFutureNull())(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:35:46: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+// - 'Future' is from 'dart:async'.
+// Future<bool> var5 = (() => getFutureNull())(); // error
+// ^
+//
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method getNull() → dynamic
+ return null;
+static method getFutureNull() → asy::Future<dynamic> /* originally async */ {
+ final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+ asy::FutureOr<dynamic>? :return_value;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L1:
+ {
+ :return_value = null;
+ break #L1;
+ }
+ asy::_completeOnAsyncReturn(:async_completer, :return_value);
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+ return :async_completer.{asy::Completer::future};
+}
+static method getFutureBool() → asy::Future<core::bool> /* originally async */ {
+ final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+ asy::FutureOr<core::bool>? :return_value;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L2:
+ {
+ :return_value = true;
+ break #L2;
+ }
+ asy::_completeOnAsyncReturn(:async_completer, :return_value);
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+ return :async_completer.{asy::Completer::future};
+}
+static method test1() → asy::Future<core::bool> /* originally async */ {
+ final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+ asy::FutureOr<core::bool>? :return_value;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L3:
+ {
+ final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:14:31: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+ - 'Future' is from 'dart:async'.
+ - 'FutureOr' is from 'dart:async'.
+Future<bool> test1() async => await getNull(); // error
+ ^";
+ [yield] let dynamic #t2 = asy::_awaitHelper(self::getNull(), :async_op_then, :async_op_error, :async_op) in null;
+ :return_value = :result as{TypeError,ForNonNullableByDefault} asy::FutureOr<core::bool>;
+ break #L3;
+ }
+ asy::_completeOnAsyncReturn(:async_completer, :return_value);
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+ return :async_completer.{asy::Completer::future};
+}
+static method test2() → asy::Future<core::bool>
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
+static method test3() → core::bool
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+static method test4() → asy::Future<core::bool> /* originally async */ {
+ final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+ asy::FutureOr<core::bool>? :return_value;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L4:
+ {
+ final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:17:31: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+ - 'Future' is from 'dart:async'.
+ - 'FutureOr' is from 'dart:async'.
+Future<bool> test4() async => await getFutureNull(); // error
+ ^";
+ [yield] let dynamic #t4 = asy::_awaitHelper(self::getFutureNull(), :async_op_then, :async_op_error, :async_op) in null;
+ :return_value = :result as{TypeError,ForNonNullableByDefault} asy::FutureOr<core::bool>;
+ break #L4;
+ }
+ asy::_completeOnAsyncReturn(:async_completer, :return_value);
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+ return :async_completer.{asy::Completer::future};
+}
+static method test5() → asy::Future<core::bool>
+ return let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:18:25: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ - 'Future' is from 'dart:async'.
+Future<bool> test5() => getFutureNull(); // error
+ ^" in self::getFutureNull() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+static method test6() → asy::Future<core::bool>
+ return self::getFutureBool();
+static method test7() → asy::Future<core::bool> /* originally async */ {
+ final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+ asy::FutureOr<core::bool>? :return_value;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L5:
+ {
+ :return_value = self::getFutureBool();
+ break #L5;
+ }
+ asy::_completeOnAsyncReturn(:async_completer, :return_value);
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+ return :async_completer.{asy::Completer::future};
+}
+static method test() → dynamic /* originally async */ {
+ final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+ asy::FutureOr<dynamic>? :return_value;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L6:
+ {
+ function test1() → asy::Future<core::bool> /* originally async */ {
+ final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+ asy::FutureOr<core::bool>? :return_value;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L7:
+ {
+ final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:23:33: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+ - 'Future' is from 'dart:async'.
+ - 'FutureOr' is from 'dart:async'.
+ Future<bool> test1() async => await getNull(); // error
+ ^";
+ [yield] let dynamic #t7 = asy::_awaitHelper(self::getNull(), :async_op_then, :async_op_error, :async_op) in null;
+ :return_value = :result as{TypeError,ForNonNullableByDefault} asy::FutureOr<core::bool>;
+ break #L7;
+ }
+ asy::_completeOnAsyncReturn(:async_completer, :return_value);
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+ return :async_completer.{asy::Completer::future};
+ }
+ function test2() → asy::Future<core::bool>
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
+ function test3() → core::bool
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+ function test4() → asy::Future<core::bool> /* originally async */ {
+ final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+ asy::FutureOr<core::bool>? :return_value;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L8:
+ {
+ final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:26:33: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+ - 'Future' is from 'dart:async'.
+ - 'FutureOr' is from 'dart:async'.
+ Future<bool> test4() async => await getFutureNull(); // error
+ ^";
+ [yield] let dynamic #t9 = asy::_awaitHelper(self::getFutureNull(), :async_op_then, :async_op_error, :async_op) in null;
+ :return_value = :result as{TypeError,ForNonNullableByDefault} asy::FutureOr<core::bool>;
+ break #L8;
+ }
+ asy::_completeOnAsyncReturn(:async_completer, :return_value);
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+ return :async_completer.{asy::Completer::future};
+ }
+ function test5() → asy::Future<core::bool>
+ return let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:27:27: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ - 'Future' is from 'dart:async'.
+ Future<bool> test5() => getFutureNull(); // error
+ ^" in self::getFutureNull() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+ function test6() → asy::Future<core::bool>
+ return self::getFutureBool();
+ function test7() → asy::Future<core::bool> /* originally async */ {
+ final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+ asy::FutureOr<core::bool>? :return_value;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L9:
+ {
+ :return_value = self::getFutureBool();
+ break #L9;
+ }
+ asy::_completeOnAsyncReturn(:async_completer, :return_value);
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+ return :async_completer.{asy::Completer::future};
+ }
+ asy::Future<core::bool> var1 = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:31:52: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ - 'Future' is from 'dart:async'.
+ Future<bool> var1 = (() async => await getNull())(); // error
+ ^" in (() → asy::Future<dynamic> /* originally async */ {
+ final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+ asy::FutureOr<dynamic>? :return_value;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L10:
+ {
+ [yield] let dynamic #t12 = asy::_awaitHelper(self::getNull(), :async_op_then, :async_op_error, :async_op) in null;
+ :return_value = :result;
+ break #L10;
+ }
+ asy::_completeOnAsyncReturn(:async_completer, :return_value);
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+ return :async_completer.{asy::Completer::future};
+ }).call() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+ asy::Future<core::bool> var2 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
+ core::bool var3 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+ asy::Future<core::bool> var4 = let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:34:58: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ - 'Future' is from 'dart:async'.
+ Future<bool> var4 = (() async => await getFutureNull())(); // error
+ ^" in (() → asy::Future<dynamic> /* originally async */ {
+ final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+ asy::FutureOr<dynamic>? :return_value;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L11:
+ {
+ [yield] let dynamic #t14 = asy::_awaitHelper(self::getFutureNull(), :async_op_then, :async_op_error, :async_op) in null;
+ :return_value = :result;
+ break #L11;
+ }
+ asy::_completeOnAsyncReturn(:async_completer, :return_value);
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+ return :async_completer.{asy::Completer::future};
+ }).call() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+ asy::Future<core::bool> var5 = let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:35:46: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ - 'Future' is from 'dart:async'.
+ Future<bool> var5 = (() => getFutureNull())(); // error
+ ^" in (() → asy::Future<dynamic> => self::getFutureNull()).call() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+ asy::Future<core::bool> var6 = (() → asy::Future<core::bool> => self::getFutureBool()).call();
+ asy::Future<core::bool> var7 = (() → asy::Future<core::bool> /* originally async */ {
+ final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+ asy::FutureOr<core::bool>? :return_value;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L12:
+ {
+ :return_value = self::getFutureBool();
+ break #L12;
+ }
+ asy::_completeOnAsyncReturn(:async_completer, :return_value);
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+ return :async_completer.{asy::Completer::future};
+ }).call();
+ }
+ asy::_completeOnAsyncReturn(:async_completer, :return_value);
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+ return :async_completer.{asy::Completer::future};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41437a.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41437a.dart.weak.expect
new file mode 100644
index 0000000..9f84dd0
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41437a.dart.weak.expect
@@ -0,0 +1,134 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:14:31: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+// - 'Future' is from 'dart:async'.
+// - 'FutureOr' is from 'dart:async'.
+// Future<bool> test1() async => await getNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:17:31: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+// - 'Future' is from 'dart:async'.
+// - 'FutureOr' is from 'dart:async'.
+// Future<bool> test4() async => await getFutureNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:18:25: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+// - 'Future' is from 'dart:async'.
+// Future<bool> test5() => getFutureNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:23:33: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+// - 'Future' is from 'dart:async'.
+// - 'FutureOr' is from 'dart:async'.
+// Future<bool> test1() async => await getNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:26:33: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+// - 'Future' is from 'dart:async'.
+// - 'FutureOr' is from 'dart:async'.
+// Future<bool> test4() async => await getFutureNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:27:27: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+// - 'Future' is from 'dart:async'.
+// Future<bool> test5() => getFutureNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:31:52: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+// - 'Future' is from 'dart:async'.
+// Future<bool> var1 = (() async => await getNull())(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:34:58: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+// - 'Future' is from 'dart:async'.
+// Future<bool> var4 = (() async => await getFutureNull())(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:35:46: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+// - 'Future' is from 'dart:async'.
+// Future<bool> var5 = (() => getFutureNull())(); // error
+// ^
+//
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method getNull() → dynamic
+ return null;
+static method getFutureNull() → asy::Future<dynamic> async {
+ return null;
+}
+static method getFutureBool() → asy::Future<core::bool> async {
+ return true;
+}
+static method test1() → asy::Future<core::bool> async
+ return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:14:31: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+ - 'Future' is from 'dart:async'.
+ - 'FutureOr' is from 'dart:async'.
+Future<bool> test1() async => await getNull(); // error
+ ^" in await self::getNull() as{TypeError,ForNonNullableByDefault} asy::FutureOr<core::bool>;
+static method test2() → asy::Future<core::bool>
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
+static method test3() → core::bool
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+static method test4() → asy::Future<core::bool> async
+ return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:17:31: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+ - 'Future' is from 'dart:async'.
+ - 'FutureOr' is from 'dart:async'.
+Future<bool> test4() async => await getFutureNull(); // error
+ ^" in await self::getFutureNull() as{TypeError,ForNonNullableByDefault} asy::FutureOr<core::bool>;
+static method test5() → asy::Future<core::bool>
+ return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:18:25: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ - 'Future' is from 'dart:async'.
+Future<bool> test5() => getFutureNull(); // error
+ ^" in self::getFutureNull() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+static method test6() → asy::Future<core::bool>
+ return self::getFutureBool();
+static method test7() → asy::Future<core::bool> async
+ return self::getFutureBool();
+static method test() → dynamic async {
+ function test1() → asy::Future<core::bool> async
+ return let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:23:33: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+ - 'Future' is from 'dart:async'.
+ - 'FutureOr' is from 'dart:async'.
+ Future<bool> test1() async => await getNull(); // error
+ ^" in await self::getNull() as{TypeError,ForNonNullableByDefault} asy::FutureOr<core::bool>;
+ function test2() → asy::Future<core::bool>
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
+ function test3() → core::bool
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+ function test4() → asy::Future<core::bool> async
+ return let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:26:33: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+ - 'Future' is from 'dart:async'.
+ - 'FutureOr' is from 'dart:async'.
+ Future<bool> test4() async => await getFutureNull(); // error
+ ^" in await self::getFutureNull() as{TypeError,ForNonNullableByDefault} asy::FutureOr<core::bool>;
+ function test5() → asy::Future<core::bool>
+ return let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:27:27: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ - 'Future' is from 'dart:async'.
+ Future<bool> test5() => getFutureNull(); // error
+ ^" in self::getFutureNull() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+ function test6() → asy::Future<core::bool>
+ return self::getFutureBool();
+ function test7() → asy::Future<core::bool> async
+ return self::getFutureBool();
+ asy::Future<core::bool> var1 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:31:52: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ - 'Future' is from 'dart:async'.
+ Future<bool> var1 = (() async => await getNull())(); // error
+ ^" in (() → asy::Future<dynamic> async => await self::getNull()).call() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+ asy::Future<core::bool> var2 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
+ core::bool var3 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+ asy::Future<core::bool> var4 = let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:34:58: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ - 'Future' is from 'dart:async'.
+ Future<bool> var4 = (() async => await getFutureNull())(); // error
+ ^" in (() → asy::Future<dynamic> async => await self::getFutureNull()).call() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+ asy::Future<core::bool> var5 = let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:35:46: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ - 'Future' is from 'dart:async'.
+ Future<bool> var5 = (() => getFutureNull())(); // error
+ ^" in (() → asy::Future<dynamic> => self::getFutureNull()).call() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+ asy::Future<core::bool> var6 = (() → asy::Future<core::bool> => self::getFutureBool()).call();
+ asy::Future<core::bool> var7 = (() → asy::Future<core::bool> async => self::getFutureBool()).call();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41437a.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41437a.dart.weak.transformed.expect
new file mode 100644
index 0000000..2e9e775
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41437a.dart.weak.transformed.expect
@@ -0,0 +1,449 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:14:31: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+// - 'Future' is from 'dart:async'.
+// - 'FutureOr' is from 'dart:async'.
+// Future<bool> test1() async => await getNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:17:31: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+// - 'Future' is from 'dart:async'.
+// - 'FutureOr' is from 'dart:async'.
+// Future<bool> test4() async => await getFutureNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:18:25: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+// - 'Future' is from 'dart:async'.
+// Future<bool> test5() => getFutureNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:23:33: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+// - 'Future' is from 'dart:async'.
+// - 'FutureOr' is from 'dart:async'.
+// Future<bool> test1() async => await getNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:26:33: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+// - 'Future' is from 'dart:async'.
+// - 'FutureOr' is from 'dart:async'.
+// Future<bool> test4() async => await getFutureNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:27:27: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+// - 'Future' is from 'dart:async'.
+// Future<bool> test5() => getFutureNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:31:52: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+// - 'Future' is from 'dart:async'.
+// Future<bool> var1 = (() async => await getNull())(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:34:58: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+// - 'Future' is from 'dart:async'.
+// Future<bool> var4 = (() async => await getFutureNull())(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437a.dart:35:46: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+// - 'Future' is from 'dart:async'.
+// Future<bool> var5 = (() => getFutureNull())(); // error
+// ^
+//
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method getNull() → dynamic
+ return null;
+static method getFutureNull() → asy::Future<dynamic> /* originally async */ {
+ final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+ asy::FutureOr<dynamic>? :return_value;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L1:
+ {
+ :return_value = null;
+ break #L1;
+ }
+ asy::_completeOnAsyncReturn(:async_completer, :return_value);
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+ return :async_completer.{asy::Completer::future};
+}
+static method getFutureBool() → asy::Future<core::bool> /* originally async */ {
+ final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+ asy::FutureOr<core::bool>? :return_value;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L2:
+ {
+ :return_value = true;
+ break #L2;
+ }
+ asy::_completeOnAsyncReturn(:async_completer, :return_value);
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+ return :async_completer.{asy::Completer::future};
+}
+static method test1() → asy::Future<core::bool> /* originally async */ {
+ final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+ asy::FutureOr<core::bool>? :return_value;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L3:
+ {
+ final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:14:31: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+ - 'Future' is from 'dart:async'.
+ - 'FutureOr' is from 'dart:async'.
+Future<bool> test1() async => await getNull(); // error
+ ^";
+ [yield] let dynamic #t2 = asy::_awaitHelper(self::getNull(), :async_op_then, :async_op_error, :async_op) in null;
+ :return_value = :result as{TypeError,ForNonNullableByDefault} asy::FutureOr<core::bool>;
+ break #L3;
+ }
+ asy::_completeOnAsyncReturn(:async_completer, :return_value);
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+ return :async_completer.{asy::Completer::future};
+}
+static method test2() → asy::Future<core::bool>
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
+static method test3() → core::bool
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+static method test4() → asy::Future<core::bool> /* originally async */ {
+ final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+ asy::FutureOr<core::bool>? :return_value;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L4:
+ {
+ final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:17:31: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+ - 'Future' is from 'dart:async'.
+ - 'FutureOr' is from 'dart:async'.
+Future<bool> test4() async => await getFutureNull(); // error
+ ^";
+ [yield] let dynamic #t4 = asy::_awaitHelper(self::getFutureNull(), :async_op_then, :async_op_error, :async_op) in null;
+ :return_value = :result as{TypeError,ForNonNullableByDefault} asy::FutureOr<core::bool>;
+ break #L4;
+ }
+ asy::_completeOnAsyncReturn(:async_completer, :return_value);
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+ return :async_completer.{asy::Completer::future};
+}
+static method test5() → asy::Future<core::bool>
+ return let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:18:25: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ - 'Future' is from 'dart:async'.
+Future<bool> test5() => getFutureNull(); // error
+ ^" in self::getFutureNull() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+static method test6() → asy::Future<core::bool>
+ return self::getFutureBool();
+static method test7() → asy::Future<core::bool> /* originally async */ {
+ final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+ asy::FutureOr<core::bool>? :return_value;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L5:
+ {
+ :return_value = self::getFutureBool();
+ break #L5;
+ }
+ asy::_completeOnAsyncReturn(:async_completer, :return_value);
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+ return :async_completer.{asy::Completer::future};
+}
+static method test() → dynamic /* originally async */ {
+ final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+ asy::FutureOr<dynamic>? :return_value;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L6:
+ {
+ function test1() → asy::Future<core::bool> /* originally async */ {
+ final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+ asy::FutureOr<core::bool>? :return_value;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L7:
+ {
+ final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:23:33: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+ - 'Future' is from 'dart:async'.
+ - 'FutureOr' is from 'dart:async'.
+ Future<bool> test1() async => await getNull(); // error
+ ^";
+ [yield] let dynamic #t7 = asy::_awaitHelper(self::getNull(), :async_op_then, :async_op_error, :async_op) in null;
+ :return_value = :result as{TypeError,ForNonNullableByDefault} asy::FutureOr<core::bool>;
+ break #L7;
+ }
+ asy::_completeOnAsyncReturn(:async_completer, :return_value);
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+ return :async_completer.{asy::Completer::future};
+ }
+ function test2() → asy::Future<core::bool>
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
+ function test3() → core::bool
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+ function test4() → asy::Future<core::bool> /* originally async */ {
+ final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+ asy::FutureOr<core::bool>? :return_value;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L8:
+ {
+ final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:26:33: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<bool>'.
+ - 'Future' is from 'dart:async'.
+ - 'FutureOr' is from 'dart:async'.
+ Future<bool> test4() async => await getFutureNull(); // error
+ ^";
+ [yield] let dynamic #t9 = asy::_awaitHelper(self::getFutureNull(), :async_op_then, :async_op_error, :async_op) in null;
+ :return_value = :result as{TypeError,ForNonNullableByDefault} asy::FutureOr<core::bool>;
+ break #L8;
+ }
+ asy::_completeOnAsyncReturn(:async_completer, :return_value);
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+ return :async_completer.{asy::Completer::future};
+ }
+ function test5() → asy::Future<core::bool>
+ return let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:27:27: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ - 'Future' is from 'dart:async'.
+ Future<bool> test5() => getFutureNull(); // error
+ ^" in self::getFutureNull() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+ function test6() → asy::Future<core::bool>
+ return self::getFutureBool();
+ function test7() → asy::Future<core::bool> /* originally async */ {
+ final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+ asy::FutureOr<core::bool>? :return_value;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L9:
+ {
+ :return_value = self::getFutureBool();
+ break #L9;
+ }
+ asy::_completeOnAsyncReturn(:async_completer, :return_value);
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+ return :async_completer.{asy::Completer::future};
+ }
+ asy::Future<core::bool> var1 = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:31:52: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ - 'Future' is from 'dart:async'.
+ Future<bool> var1 = (() async => await getNull())(); // error
+ ^" in (() → asy::Future<dynamic> /* originally async */ {
+ final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+ asy::FutureOr<dynamic>? :return_value;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L10:
+ {
+ [yield] let dynamic #t12 = asy::_awaitHelper(self::getNull(), :async_op_then, :async_op_error, :async_op) in null;
+ :return_value = :result;
+ break #L10;
+ }
+ asy::_completeOnAsyncReturn(:async_completer, :return_value);
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+ return :async_completer.{asy::Completer::future};
+ }).call() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+ asy::Future<core::bool> var2 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
+ core::bool var3 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+ asy::Future<core::bool> var4 = let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:34:58: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ - 'Future' is from 'dart:async'.
+ Future<bool> var4 = (() async => await getFutureNull())(); // error
+ ^" in (() → asy::Future<dynamic> /* originally async */ {
+ final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+ asy::FutureOr<dynamic>? :return_value;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L11:
+ {
+ [yield] let dynamic #t14 = asy::_awaitHelper(self::getFutureNull(), :async_op_then, :async_op_error, :async_op) in null;
+ :return_value = :result;
+ break #L11;
+ }
+ asy::_completeOnAsyncReturn(:async_completer, :return_value);
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+ return :async_completer.{asy::Completer::future};
+ }).call() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+ asy::Future<core::bool> var5 = let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:35:46: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ - 'Future' is from 'dart:async'.
+ Future<bool> var5 = (() => getFutureNull())(); // error
+ ^" in (() → asy::Future<dynamic> => self::getFutureNull()).call() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+ asy::Future<core::bool> var6 = (() → asy::Future<core::bool> => self::getFutureBool()).call();
+ asy::Future<core::bool> var7 = (() → asy::Future<core::bool> /* originally async */ {
+ final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+ asy::FutureOr<core::bool>? :return_value;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L12:
+ {
+ :return_value = self::getFutureBool();
+ break #L12;
+ }
+ asy::_completeOnAsyncReturn(:async_completer, :return_value);
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+ return :async_completer.{asy::Completer::future};
+ }).call();
+ }
+ asy::_completeOnAsyncReturn(:async_completer, :return_value);
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+ return :async_completer.{asy::Completer::future};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41437b.dart b/pkg/front_end/testcases/nnbd/issue41437b.dart
new file mode 100644
index 0000000..6a03c65
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41437b.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+dynamic getNull() => null;
+Iterable<dynamic> getIterableNull() sync* {
+ yield null;
+}
+
+Iterable<bool> getIterableBool() sync* {
+ yield true;
+}
+
+Iterable<bool> test1() sync* {
+ yield getNull(); // ok
+}
+
+Iterable<bool> test2() => getNull(); // ok
+bool test3() => getNull(); // ok
+Iterable<bool> test4() sync* {
+ yield* getIterableNull(); // error
+}
+
+Iterable<bool> test5() => getIterableNull(); // error
+Iterable<bool> test6() => getIterableBool(); // ok
+Iterable<bool> test7() sync* {
+ yield* getIterableBool(); // ok
+}
+
+test() async {
+ Iterable<bool> test1() sync* {
+ yield getNull(); // ok
+ }
+
+ Iterable<bool> test2() => getNull(); // ok
+ bool test3() => getNull(); // ok
+ Iterable<bool> test4() sync* {
+ yield* getIterableNull(); // error
+ }
+
+ Iterable<bool> test5() => getIterableNull(); // error
+ Iterable<bool> test6() => getIterableBool(); // ok
+ Iterable<bool> test7() sync* {
+ yield* getIterableBool(); // ok
+ }
+
+ Iterable<bool> var1 = (() sync* {
+ yield getNull();
+ })(); // error
+ Iterable<bool> var2 = (() => getNull())(); // ok
+ bool var3 = (() => getNull())(); // ok
+ Iterable<bool> var4 = (() sync* {
+ yield* getIterableNull();
+ })(); // error
+ Iterable<bool> var5 = (() => getIterableNull())(); // error
+ Iterable<bool> var6 = (() => getIterableBool())(); // ok
+ Iterable<bool> var7 = (() sync* {
+ yield* getIterableBool();
+ })(); // ok
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41437b.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue41437b.dart.outline.expect
new file mode 100644
index 0000000..ab30e91
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41437b.dart.outline.expect
@@ -0,0 +1,28 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method getNull() → dynamic
+ ;
+static method getIterableNull() → core::Iterable<dynamic>
+ ;
+static method getIterableBool() → core::Iterable<core::bool>
+ ;
+static method test1() → core::Iterable<core::bool>
+ ;
+static method test2() → core::Iterable<core::bool>
+ ;
+static method test3() → core::bool
+ ;
+static method test4() → core::Iterable<core::bool>
+ ;
+static method test5() → core::Iterable<core::bool>
+ ;
+static method test6() → core::Iterable<core::bool>
+ ;
+static method test7() → core::Iterable<core::bool>
+ ;
+static method test() → dynamic
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/nnbd/issue41437b.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41437b.dart.strong.expect
new file mode 100644
index 0000000..3c4069e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41437b.dart.strong.expect
@@ -0,0 +1,121 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:21:10: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+// - 'Iterable' is from 'dart:core'.
+// yield* getIterableNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:24:27: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+// - 'Iterable' is from 'dart:core'.
+// Iterable<bool> test5() => getIterableNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:38:12: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+// - 'Iterable' is from 'dart:core'.
+// yield* getIterableNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:41:29: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+// - 'Iterable' is from 'dart:core'.
+// Iterable<bool> test5() => getIterableNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:49:5: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+// - 'Iterable' is from 'dart:core'.
+// })(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:54:5: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+// - 'Iterable' is from 'dart:core'.
+// })(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:55:50: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+// - 'Iterable' is from 'dart:core'.
+// Iterable<bool> var5 = (() => getIterableNull())(); // error
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+static method getNull() → dynamic
+ return null;
+static method getIterableNull() → core::Iterable<dynamic> sync* {
+ yield null;
+}
+static method getIterableBool() → core::Iterable<core::bool> sync* {
+ yield true;
+}
+static method test1() → core::Iterable<core::bool> sync* {
+ yield self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+}
+static method test2() → core::Iterable<core::bool>
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<core::bool>;
+static method test3() → core::bool
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+static method test4() → core::Iterable<core::bool> sync* {
+ yield* let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:21:10: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+ yield* getIterableNull(); // error
+ ^" in self::getIterableNull() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+}
+static method test5() → core::Iterable<core::bool>
+ return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:24:27: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+Iterable<bool> test5() => getIterableNull(); // error
+ ^" in self::getIterableNull() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+static method test6() → core::Iterable<core::bool>
+ return self::getIterableBool();
+static method test7() → core::Iterable<core::bool> sync* {
+ yield* self::getIterableBool();
+}
+static method test() → dynamic async {
+ function test1() → core::Iterable<core::bool> sync* {
+ yield self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+ }
+ function test2() → core::Iterable<core::bool>
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<core::bool>;
+ function test3() → core::bool
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+ function test4() → core::Iterable<core::bool> sync* {
+ yield* let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:38:12: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+ yield* getIterableNull(); // error
+ ^" in self::getIterableNull() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+ }
+ function test5() → core::Iterable<core::bool>
+ return let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:41:29: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+ Iterable<bool> test5() => getIterableNull(); // error
+ ^" in self::getIterableNull() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+ function test6() → core::Iterable<core::bool>
+ return self::getIterableBool();
+ function test7() → core::Iterable<core::bool> sync* {
+ yield* self::getIterableBool();
+ }
+ core::Iterable<core::bool> var1 = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:49:5: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+ })(); // error
+ ^" in (() → core::Iterable<dynamic> sync* {
+ yield self::getNull();
+ }).call() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+ core::Iterable<core::bool> var2 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<core::bool>;
+ core::bool var3 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+ core::Iterable<core::bool> var4 = let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:54:5: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+ })(); // error
+ ^" in (() → core::Iterable<dynamic> sync* {
+ yield* self::getIterableNull();
+ }).call() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+ core::Iterable<core::bool> var5 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:55:50: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+ Iterable<bool> var5 = (() => getIterableNull())(); // error
+ ^" in (() → core::Iterable<dynamic> => self::getIterableNull()).call() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+ core::Iterable<core::bool> var6 = (() → core::Iterable<core::bool> => self::getIterableBool()).call();
+ core::Iterable<core::bool> var7 = (() → core::Iterable<core::bool> sync* {
+ yield* self::getIterableBool();
+ }).call();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41437b.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41437b.dart.strong.transformed.expect
new file mode 100644
index 0000000..07830cd
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41437b.dart.strong.transformed.expect
@@ -0,0 +1,266 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:21:10: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+// - 'Iterable' is from 'dart:core'.
+// yield* getIterableNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:24:27: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+// - 'Iterable' is from 'dart:core'.
+// Iterable<bool> test5() => getIterableNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:38:12: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+// - 'Iterable' is from 'dart:core'.
+// yield* getIterableNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:41:29: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+// - 'Iterable' is from 'dart:core'.
+// Iterable<bool> test5() => getIterableNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:49:5: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+// - 'Iterable' is from 'dart:core'.
+// })(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:54:5: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+// - 'Iterable' is from 'dart:core'.
+// })(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:55:50: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+// - 'Iterable' is from 'dart:core'.
+// Iterable<bool> var5 = (() => getIterableNull())(); // error
+// ^
+//
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+static method getNull() → dynamic
+ return null;
+static method getIterableNull() → core::Iterable<dynamic> /* originally sync* */ {
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :sync_op(core::_SyncIterator<dynamic>? :iterator) → core::bool* yielding {
+ {
+ {
+ :iterator.{core::_SyncIterator::_current} = null;
+ [yield] true;
+ }
+ }
+ return false;
+ }
+ return new core::_SyncIterable::•<dynamic>(:sync_op);
+}
+static method getIterableBool() → core::Iterable<core::bool> /* originally sync* */ {
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :sync_op(core::_SyncIterator<core::bool>? :iterator) → core::bool* yielding {
+ {
+ {
+ :iterator.{core::_SyncIterator::_current} = true;
+ [yield] true;
+ }
+ }
+ return false;
+ }
+ return new core::_SyncIterable::•<core::bool>(:sync_op);
+}
+static method test1() → core::Iterable<core::bool> /* originally sync* */ {
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :sync_op(core::_SyncIterator<core::bool>? :iterator) → core::bool* yielding {
+ {
+ {
+ :iterator.{core::_SyncIterator::_current} = self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+ [yield] true;
+ }
+ }
+ return false;
+ }
+ return new core::_SyncIterable::•<core::bool>(:sync_op);
+}
+static method test2() → core::Iterable<core::bool>
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<core::bool>;
+static method test3() → core::bool
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+static method test4() → core::Iterable<core::bool> /* originally sync* */ {
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :sync_op(core::_SyncIterator<core::bool>? :iterator) → core::bool* yielding {
+ {
+ {
+ :iterator.{core::_SyncIterator::_yieldEachIterable} = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:21:10: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+ yield* getIterableNull(); // error
+ ^" in self::getIterableNull() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+ [yield] true;
+ }
+ }
+ return false;
+ }
+ return new core::_SyncIterable::•<core::bool>(:sync_op);
+}
+static method test5() → core::Iterable<core::bool>
+ return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:24:27: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+Iterable<bool> test5() => getIterableNull(); // error
+ ^" in self::getIterableNull() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+static method test6() → core::Iterable<core::bool>
+ return self::getIterableBool();
+static method test7() → core::Iterable<core::bool> /* originally sync* */ {
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :sync_op(core::_SyncIterator<core::bool>? :iterator) → core::bool* yielding {
+ {
+ {
+ :iterator.{core::_SyncIterator::_yieldEachIterable} = self::getIterableBool();
+ [yield] true;
+ }
+ }
+ return false;
+ }
+ return new core::_SyncIterable::•<core::bool>(:sync_op);
+}
+static method test() → dynamic /* originally async */ {
+ final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+ asy::FutureOr<dynamic>? :return_value;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L1:
+ {
+ function test1() → core::Iterable<core::bool> /* originally sync* */ {
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :sync_op(core::_SyncIterator<core::bool>? :iterator) → core::bool* yielding {
+ {
+ {
+ :iterator.{core::_SyncIterator::_current} = self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+ [yield] true;
+ }
+ }
+ return false;
+ }
+ return new core::_SyncIterable::•<core::bool>(:sync_op);
+ }
+ function test2() → core::Iterable<core::bool>
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<core::bool>;
+ function test3() → core::bool
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+ function test4() → core::Iterable<core::bool> /* originally sync* */ {
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :sync_op(core::_SyncIterator<core::bool>? :iterator) → core::bool* yielding {
+ {
+ {
+ :iterator.{core::_SyncIterator::_yieldEachIterable} = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:38:12: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+ yield* getIterableNull(); // error
+ ^" in self::getIterableNull() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+ [yield] true;
+ }
+ }
+ return false;
+ }
+ return new core::_SyncIterable::•<core::bool>(:sync_op);
+ }
+ function test5() → core::Iterable<core::bool>
+ return let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:41:29: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+ Iterable<bool> test5() => getIterableNull(); // error
+ ^" in self::getIterableNull() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+ function test6() → core::Iterable<core::bool>
+ return self::getIterableBool();
+ function test7() → core::Iterable<core::bool> /* originally sync* */ {
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :sync_op(core::_SyncIterator<core::bool>? :iterator) → core::bool* yielding {
+ {
+ {
+ :iterator.{core::_SyncIterator::_yieldEachIterable} = self::getIterableBool();
+ [yield] true;
+ }
+ }
+ return false;
+ }
+ return new core::_SyncIterable::•<core::bool>(:sync_op);
+ }
+ core::Iterable<core::bool> var1 = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:49:5: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+ })(); // error
+ ^" in (() → core::Iterable<dynamic> /* originally sync* */ {
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :sync_op(core::_SyncIterator<dynamic>? :iterator) → core::bool* yielding {
+ {
+ {
+ :iterator.{core::_SyncIterator::_current} = self::getNull();
+ [yield] true;
+ }
+ }
+ return false;
+ }
+ return new core::_SyncIterable::•<dynamic>(:sync_op);
+ }).call() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+ core::Iterable<core::bool> var2 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<core::bool>;
+ core::bool var3 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+ core::Iterable<core::bool> var4 = let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:54:5: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+ })(); // error
+ ^" in (() → core::Iterable<dynamic> /* originally sync* */ {
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :sync_op(core::_SyncIterator<dynamic>? :iterator) → core::bool* yielding {
+ {
+ {
+ :iterator.{core::_SyncIterator::_yieldEachIterable} = self::getIterableNull();
+ [yield] true;
+ }
+ }
+ return false;
+ }
+ return new core::_SyncIterable::•<dynamic>(:sync_op);
+ }).call() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+ core::Iterable<core::bool> var5 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:55:50: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+ Iterable<bool> var5 = (() => getIterableNull())(); // error
+ ^" in (() → core::Iterable<dynamic> => self::getIterableNull()).call() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+ core::Iterable<core::bool> var6 = (() → core::Iterable<core::bool> => self::getIterableBool()).call();
+ core::Iterable<core::bool> var7 = (() → core::Iterable<core::bool> /* originally sync* */ {
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :sync_op(core::_SyncIterator<core::bool>? :iterator) → core::bool* yielding {
+ {
+ {
+ :iterator.{core::_SyncIterator::_yieldEachIterable} = self::getIterableBool();
+ [yield] true;
+ }
+ }
+ return false;
+ }
+ return new core::_SyncIterable::•<core::bool>(:sync_op);
+ }).call();
+ }
+ asy::_completeOnAsyncReturn(:async_completer, :return_value);
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+ return :async_completer.{asy::Completer::future};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41437b.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41437b.dart.weak.expect
new file mode 100644
index 0000000..3c4069e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41437b.dart.weak.expect
@@ -0,0 +1,121 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:21:10: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+// - 'Iterable' is from 'dart:core'.
+// yield* getIterableNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:24:27: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+// - 'Iterable' is from 'dart:core'.
+// Iterable<bool> test5() => getIterableNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:38:12: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+// - 'Iterable' is from 'dart:core'.
+// yield* getIterableNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:41:29: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+// - 'Iterable' is from 'dart:core'.
+// Iterable<bool> test5() => getIterableNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:49:5: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+// - 'Iterable' is from 'dart:core'.
+// })(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:54:5: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+// - 'Iterable' is from 'dart:core'.
+// })(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:55:50: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+// - 'Iterable' is from 'dart:core'.
+// Iterable<bool> var5 = (() => getIterableNull())(); // error
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+static method getNull() → dynamic
+ return null;
+static method getIterableNull() → core::Iterable<dynamic> sync* {
+ yield null;
+}
+static method getIterableBool() → core::Iterable<core::bool> sync* {
+ yield true;
+}
+static method test1() → core::Iterable<core::bool> sync* {
+ yield self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+}
+static method test2() → core::Iterable<core::bool>
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<core::bool>;
+static method test3() → core::bool
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+static method test4() → core::Iterable<core::bool> sync* {
+ yield* let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:21:10: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+ yield* getIterableNull(); // error
+ ^" in self::getIterableNull() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+}
+static method test5() → core::Iterable<core::bool>
+ return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:24:27: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+Iterable<bool> test5() => getIterableNull(); // error
+ ^" in self::getIterableNull() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+static method test6() → core::Iterable<core::bool>
+ return self::getIterableBool();
+static method test7() → core::Iterable<core::bool> sync* {
+ yield* self::getIterableBool();
+}
+static method test() → dynamic async {
+ function test1() → core::Iterable<core::bool> sync* {
+ yield self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+ }
+ function test2() → core::Iterable<core::bool>
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<core::bool>;
+ function test3() → core::bool
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+ function test4() → core::Iterable<core::bool> sync* {
+ yield* let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:38:12: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+ yield* getIterableNull(); // error
+ ^" in self::getIterableNull() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+ }
+ function test5() → core::Iterable<core::bool>
+ return let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:41:29: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+ Iterable<bool> test5() => getIterableNull(); // error
+ ^" in self::getIterableNull() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+ function test6() → core::Iterable<core::bool>
+ return self::getIterableBool();
+ function test7() → core::Iterable<core::bool> sync* {
+ yield* self::getIterableBool();
+ }
+ core::Iterable<core::bool> var1 = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:49:5: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+ })(); // error
+ ^" in (() → core::Iterable<dynamic> sync* {
+ yield self::getNull();
+ }).call() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+ core::Iterable<core::bool> var2 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<core::bool>;
+ core::bool var3 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+ core::Iterable<core::bool> var4 = let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:54:5: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+ })(); // error
+ ^" in (() → core::Iterable<dynamic> sync* {
+ yield* self::getIterableNull();
+ }).call() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+ core::Iterable<core::bool> var5 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:55:50: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+ Iterable<bool> var5 = (() => getIterableNull())(); // error
+ ^" in (() → core::Iterable<dynamic> => self::getIterableNull()).call() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+ core::Iterable<core::bool> var6 = (() → core::Iterable<core::bool> => self::getIterableBool()).call();
+ core::Iterable<core::bool> var7 = (() → core::Iterable<core::bool> sync* {
+ yield* self::getIterableBool();
+ }).call();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41437b.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41437b.dart.weak.transformed.expect
new file mode 100644
index 0000000..07830cd
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41437b.dart.weak.transformed.expect
@@ -0,0 +1,266 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:21:10: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+// - 'Iterable' is from 'dart:core'.
+// yield* getIterableNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:24:27: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+// - 'Iterable' is from 'dart:core'.
+// Iterable<bool> test5() => getIterableNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:38:12: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+// - 'Iterable' is from 'dart:core'.
+// yield* getIterableNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:41:29: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+// - 'Iterable' is from 'dart:core'.
+// Iterable<bool> test5() => getIterableNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:49:5: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+// - 'Iterable' is from 'dart:core'.
+// })(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:54:5: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+// - 'Iterable' is from 'dart:core'.
+// })(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437b.dart:55:50: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+// - 'Iterable' is from 'dart:core'.
+// Iterable<bool> var5 = (() => getIterableNull())(); // error
+// ^
+//
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+static method getNull() → dynamic
+ return null;
+static method getIterableNull() → core::Iterable<dynamic> /* originally sync* */ {
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :sync_op(core::_SyncIterator<dynamic>? :iterator) → core::bool* yielding {
+ {
+ {
+ :iterator.{core::_SyncIterator::_current} = null;
+ [yield] true;
+ }
+ }
+ return false;
+ }
+ return new core::_SyncIterable::•<dynamic>(:sync_op);
+}
+static method getIterableBool() → core::Iterable<core::bool> /* originally sync* */ {
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :sync_op(core::_SyncIterator<core::bool>? :iterator) → core::bool* yielding {
+ {
+ {
+ :iterator.{core::_SyncIterator::_current} = true;
+ [yield] true;
+ }
+ }
+ return false;
+ }
+ return new core::_SyncIterable::•<core::bool>(:sync_op);
+}
+static method test1() → core::Iterable<core::bool> /* originally sync* */ {
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :sync_op(core::_SyncIterator<core::bool>? :iterator) → core::bool* yielding {
+ {
+ {
+ :iterator.{core::_SyncIterator::_current} = self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+ [yield] true;
+ }
+ }
+ return false;
+ }
+ return new core::_SyncIterable::•<core::bool>(:sync_op);
+}
+static method test2() → core::Iterable<core::bool>
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<core::bool>;
+static method test3() → core::bool
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+static method test4() → core::Iterable<core::bool> /* originally sync* */ {
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :sync_op(core::_SyncIterator<core::bool>? :iterator) → core::bool* yielding {
+ {
+ {
+ :iterator.{core::_SyncIterator::_yieldEachIterable} = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:21:10: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+ yield* getIterableNull(); // error
+ ^" in self::getIterableNull() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+ [yield] true;
+ }
+ }
+ return false;
+ }
+ return new core::_SyncIterable::•<core::bool>(:sync_op);
+}
+static method test5() → core::Iterable<core::bool>
+ return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:24:27: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+Iterable<bool> test5() => getIterableNull(); // error
+ ^" in self::getIterableNull() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+static method test6() → core::Iterable<core::bool>
+ return self::getIterableBool();
+static method test7() → core::Iterable<core::bool> /* originally sync* */ {
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :sync_op(core::_SyncIterator<core::bool>? :iterator) → core::bool* yielding {
+ {
+ {
+ :iterator.{core::_SyncIterator::_yieldEachIterable} = self::getIterableBool();
+ [yield] true;
+ }
+ }
+ return false;
+ }
+ return new core::_SyncIterable::•<core::bool>(:sync_op);
+}
+static method test() → dynamic /* originally async */ {
+ final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+ asy::FutureOr<dynamic>? :return_value;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L1:
+ {
+ function test1() → core::Iterable<core::bool> /* originally sync* */ {
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :sync_op(core::_SyncIterator<core::bool>? :iterator) → core::bool* yielding {
+ {
+ {
+ :iterator.{core::_SyncIterator::_current} = self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+ [yield] true;
+ }
+ }
+ return false;
+ }
+ return new core::_SyncIterable::•<core::bool>(:sync_op);
+ }
+ function test2() → core::Iterable<core::bool>
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<core::bool>;
+ function test3() → core::bool
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+ function test4() → core::Iterable<core::bool> /* originally sync* */ {
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :sync_op(core::_SyncIterator<core::bool>? :iterator) → core::bool* yielding {
+ {
+ {
+ :iterator.{core::_SyncIterator::_yieldEachIterable} = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:38:12: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+ yield* getIterableNull(); // error
+ ^" in self::getIterableNull() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+ [yield] true;
+ }
+ }
+ return false;
+ }
+ return new core::_SyncIterable::•<core::bool>(:sync_op);
+ }
+ function test5() → core::Iterable<core::bool>
+ return let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:41:29: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+ Iterable<bool> test5() => getIterableNull(); // error
+ ^" in self::getIterableNull() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+ function test6() → core::Iterable<core::bool>
+ return self::getIterableBool();
+ function test7() → core::Iterable<core::bool> /* originally sync* */ {
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :sync_op(core::_SyncIterator<core::bool>? :iterator) → core::bool* yielding {
+ {
+ {
+ :iterator.{core::_SyncIterator::_yieldEachIterable} = self::getIterableBool();
+ [yield] true;
+ }
+ }
+ return false;
+ }
+ return new core::_SyncIterable::•<core::bool>(:sync_op);
+ }
+ core::Iterable<core::bool> var1 = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:49:5: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+ })(); // error
+ ^" in (() → core::Iterable<dynamic> /* originally sync* */ {
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :sync_op(core::_SyncIterator<dynamic>? :iterator) → core::bool* yielding {
+ {
+ {
+ :iterator.{core::_SyncIterator::_current} = self::getNull();
+ [yield] true;
+ }
+ }
+ return false;
+ }
+ return new core::_SyncIterable::•<dynamic>(:sync_op);
+ }).call() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+ core::Iterable<core::bool> var2 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<core::bool>;
+ core::bool var3 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+ core::Iterable<core::bool> var4 = let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:54:5: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+ })(); // error
+ ^" in (() → core::Iterable<dynamic> /* originally sync* */ {
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :sync_op(core::_SyncIterator<dynamic>? :iterator) → core::bool* yielding {
+ {
+ {
+ :iterator.{core::_SyncIterator::_yieldEachIterable} = self::getIterableNull();
+ [yield] true;
+ }
+ }
+ return false;
+ }
+ return new core::_SyncIterable::•<dynamic>(:sync_op);
+ }).call() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+ core::Iterable<core::bool> var5 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:55:50: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
+ - 'Iterable' is from 'dart:core'.
+ Iterable<bool> var5 = (() => getIterableNull())(); // error
+ ^" in (() → core::Iterable<dynamic> => self::getIterableNull()).call() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
+ core::Iterable<core::bool> var6 = (() → core::Iterable<core::bool> => self::getIterableBool()).call();
+ core::Iterable<core::bool> var7 = (() → core::Iterable<core::bool> /* originally sync* */ {
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :sync_op(core::_SyncIterator<core::bool>? :iterator) → core::bool* yielding {
+ {
+ {
+ :iterator.{core::_SyncIterator::_yieldEachIterable} = self::getIterableBool();
+ [yield] true;
+ }
+ }
+ return false;
+ }
+ return new core::_SyncIterable::•<core::bool>(:sync_op);
+ }).call();
+ }
+ asy::_completeOnAsyncReturn(:async_completer, :return_value);
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+ return :async_completer.{asy::Completer::future};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41437c.dart b/pkg/front_end/testcases/nnbd/issue41437c.dart
new file mode 100644
index 0000000..2be47c3
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41437c.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+dynamic getNull() => null;
+Stream<dynamic> getStreamNull() async* {
+ yield null;
+}
+
+Stream<bool> getStreamBool() async* {
+ yield true;
+}
+
+Stream<bool> test1() async* {
+ yield getNull(); // ok
+}
+
+Stream<bool> test2() => getNull(); // ok
+bool test3() => getNull(); // ok
+Stream<bool> test4() async* {
+ yield* getStreamNull(); // error
+}
+
+Stream<bool> test5() => getStreamNull(); // error
+Stream<bool> test6() => getStreamBool(); // ok
+Stream<bool> test7() async* {
+ yield* getStreamBool(); // ok
+}
+
+test() async {
+ Stream<bool> test1() async* {
+ yield getNull(); // ok
+ }
+
+ Stream<bool> test2() => getNull(); // ok
+ bool test3() => getNull(); // ok
+ Stream<bool> test4() async* {
+ yield* getStreamNull(); // error
+ }
+
+ Stream<bool> test5() => getStreamNull(); // error
+ Stream<bool> test6() => getStreamBool(); // ok
+ Stream<bool> test7() async* {
+ yield* getStreamBool(); // ok
+ }
+
+ Stream<bool> var1 = (() async* {
+ yield getNull();
+ })(); // error
+ Stream<bool> var2 = (() => getNull())(); // ok
+ bool var3 = (() => getNull())(); // ok
+ Stream<bool> var4 = (() async* {
+ yield* getStreamNull();
+ })(); // error
+ Stream<bool> var5 = (() => getStreamNull())(); // error
+ Stream<bool> var6 = (() => getStreamBool())(); // ok
+ Stream<bool> var7 = (() async* {
+ yield* getStreamBool();
+ })(); // ok
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41437c.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue41437c.dart.outline.expect
new file mode 100644
index 0000000..f877e4d
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41437c.dart.outline.expect
@@ -0,0 +1,29 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method getNull() → dynamic
+ ;
+static method getStreamNull() → asy::Stream<dynamic>
+ ;
+static method getStreamBool() → asy::Stream<core::bool>
+ ;
+static method test1() → asy::Stream<core::bool>
+ ;
+static method test2() → asy::Stream<core::bool>
+ ;
+static method test3() → core::bool
+ ;
+static method test4() → asy::Stream<core::bool>
+ ;
+static method test5() → asy::Stream<core::bool>
+ ;
+static method test6() → asy::Stream<core::bool>
+ ;
+static method test7() → asy::Stream<core::bool>
+ ;
+static method test() → dynamic
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/nnbd/issue41437c.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41437c.dart.strong.expect
new file mode 100644
index 0000000..16b4fb1
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41437c.dart.strong.expect
@@ -0,0 +1,122 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:21:10: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+// - 'Stream' is from 'dart:async'.
+// yield* getStreamNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:24:25: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+// - 'Stream' is from 'dart:async'.
+// Stream<bool> test5() => getStreamNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:38:12: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+// - 'Stream' is from 'dart:async'.
+// yield* getStreamNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:41:27: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+// - 'Stream' is from 'dart:async'.
+// Stream<bool> test5() => getStreamNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:49:5: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+// - 'Stream' is from 'dart:async'.
+// })(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:54:5: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+// - 'Stream' is from 'dart:async'.
+// })(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:55:46: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+// - 'Stream' is from 'dart:async'.
+// Stream<bool> var5 = (() => getStreamNull())(); // error
+// ^
+//
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method getNull() → dynamic
+ return null;
+static method getStreamNull() → asy::Stream<dynamic> async* {
+ yield null;
+}
+static method getStreamBool() → asy::Stream<core::bool> async* {
+ yield true;
+}
+static method test1() → asy::Stream<core::bool> async* {
+ yield self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+}
+static method test2() → asy::Stream<core::bool>
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<core::bool>;
+static method test3() → core::bool
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+static method test4() → asy::Stream<core::bool> async* {
+ yield* let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:21:10: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+ yield* getStreamNull(); // error
+ ^" in self::getStreamNull() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+}
+static method test5() → asy::Stream<core::bool>
+ return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:24:25: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+Stream<bool> test5() => getStreamNull(); // error
+ ^" in self::getStreamNull() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+static method test6() → asy::Stream<core::bool>
+ return self::getStreamBool();
+static method test7() → asy::Stream<core::bool> async* {
+ yield* self::getStreamBool();
+}
+static method test() → dynamic async {
+ function test1() → asy::Stream<core::bool> async* {
+ yield self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+ }
+ function test2() → asy::Stream<core::bool>
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<core::bool>;
+ function test3() → core::bool
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+ function test4() → asy::Stream<core::bool> async* {
+ yield* let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:38:12: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+ yield* getStreamNull(); // error
+ ^" in self::getStreamNull() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+ }
+ function test5() → asy::Stream<core::bool>
+ return let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:41:27: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+ Stream<bool> test5() => getStreamNull(); // error
+ ^" in self::getStreamNull() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+ function test6() → asy::Stream<core::bool>
+ return self::getStreamBool();
+ function test7() → asy::Stream<core::bool> async* {
+ yield* self::getStreamBool();
+ }
+ asy::Stream<core::bool> var1 = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:49:5: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+ })(); // error
+ ^" in (() → asy::Stream<dynamic> async* {
+ yield self::getNull();
+ }).call() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+ asy::Stream<core::bool> var2 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<core::bool>;
+ core::bool var3 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+ asy::Stream<core::bool> var4 = let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:54:5: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+ })(); // error
+ ^" in (() → asy::Stream<dynamic> async* {
+ yield* self::getStreamNull();
+ }).call() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+ asy::Stream<core::bool> var5 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:55:46: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+ Stream<bool> var5 = (() => getStreamNull())(); // error
+ ^" in (() → asy::Stream<dynamic> => self::getStreamNull()).call() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+ asy::Stream<core::bool> var6 = (() → asy::Stream<core::bool> => self::getStreamBool()).call();
+ asy::Stream<core::bool> var7 = (() → asy::Stream<core::bool> async* {
+ yield* self::getStreamBool();
+ }).call();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41437c.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41437c.dart.strong.transformed.expect
new file mode 100644
index 0000000..26e901c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41437c.dart.strong.transformed.expect
@@ -0,0 +1,497 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:21:10: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+// - 'Stream' is from 'dart:async'.
+// yield* getStreamNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:24:25: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+// - 'Stream' is from 'dart:async'.
+// Stream<bool> test5() => getStreamNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:38:12: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+// - 'Stream' is from 'dart:async'.
+// yield* getStreamNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:41:27: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+// - 'Stream' is from 'dart:async'.
+// Stream<bool> test5() => getStreamNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:49:5: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+// - 'Stream' is from 'dart:async'.
+// })(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:54:5: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+// - 'Stream' is from 'dart:async'.
+// })(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:55:46: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+// - 'Stream' is from 'dart:async'.
+// Stream<bool> var5 = (() => getStreamNull())(); // error
+// ^
+//
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method getNull() → dynamic
+ return null;
+static method getStreamNull() → asy::Stream<dynamic> /* originally async* */ {
+ asy::_AsyncStarStreamController<dynamic>? :controller;
+ dynamic :controller_stream;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ dynamic :saved_try_context_var1;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try
+ try {
+ #L1:
+ {
+ if(:controller.{asy::_AsyncStarStreamController::add}(null))
+ return null;
+ else
+ [yield] null;
+ }
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+ }
+ finally {
+ :controller.{asy::_AsyncStarStreamController::close}();
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :controller = new asy::_AsyncStarStreamController::•<dynamic>(:async_op);
+ :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+ return :controller_stream;
+}
+static method getStreamBool() → asy::Stream<core::bool> /* originally async* */ {
+ asy::_AsyncStarStreamController<core::bool>? :controller;
+ dynamic :controller_stream;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ dynamic :saved_try_context_var1;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try
+ try {
+ #L2:
+ {
+ if(:controller.{asy::_AsyncStarStreamController::add}(true))
+ return null;
+ else
+ [yield] null;
+ }
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+ }
+ finally {
+ :controller.{asy::_AsyncStarStreamController::close}();
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
+ :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+ return :controller_stream;
+}
+static method test1() → asy::Stream<core::bool> /* originally async* */ {
+ asy::_AsyncStarStreamController<core::bool>? :controller;
+ dynamic :controller_stream;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ dynamic :saved_try_context_var1;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try
+ try {
+ #L3:
+ {
+ if(:controller.{asy::_AsyncStarStreamController::add}(self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool))
+ return null;
+ else
+ [yield] null;
+ }
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+ }
+ finally {
+ :controller.{asy::_AsyncStarStreamController::close}();
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
+ :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+ return :controller_stream;
+}
+static method test2() → asy::Stream<core::bool>
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<core::bool>;
+static method test3() → core::bool
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+static method test4() → asy::Stream<core::bool> /* originally async* */ {
+ asy::_AsyncStarStreamController<core::bool>? :controller;
+ dynamic :controller_stream;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ dynamic :saved_try_context_var1;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try
+ try {
+ #L4:
+ {
+ if(:controller.{asy::_AsyncStarStreamController::addStream}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:21:10: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+ yield* getStreamNull(); // error
+ ^" in self::getStreamNull() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>))
+ return null;
+ else
+ [yield] null;
+ }
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+ }
+ finally {
+ :controller.{asy::_AsyncStarStreamController::close}();
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
+ :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+ return :controller_stream;
+}
+static method test5() → asy::Stream<core::bool>
+ return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:24:25: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+Stream<bool> test5() => getStreamNull(); // error
+ ^" in self::getStreamNull() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+static method test6() → asy::Stream<core::bool>
+ return self::getStreamBool();
+static method test7() → asy::Stream<core::bool> /* originally async* */ {
+ asy::_AsyncStarStreamController<core::bool>? :controller;
+ dynamic :controller_stream;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ dynamic :saved_try_context_var1;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try
+ try {
+ #L5:
+ {
+ if(:controller.{asy::_AsyncStarStreamController::addStream}(self::getStreamBool()))
+ return null;
+ else
+ [yield] null;
+ }
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+ }
+ finally {
+ :controller.{asy::_AsyncStarStreamController::close}();
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
+ :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+ return :controller_stream;
+}
+static method test() → dynamic /* originally async */ {
+ final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+ asy::FutureOr<dynamic>? :return_value;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L6:
+ {
+ function test1() → asy::Stream<core::bool> /* originally async* */ {
+ asy::_AsyncStarStreamController<core::bool>? :controller;
+ dynamic :controller_stream;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ dynamic :saved_try_context_var1;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try
+ try {
+ #L7:
+ {
+ if(:controller.{asy::_AsyncStarStreamController::add}(self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool))
+ return null;
+ else
+ [yield] null;
+ }
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+ }
+ finally {
+ :controller.{asy::_AsyncStarStreamController::close}();
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
+ :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+ return :controller_stream;
+ }
+ function test2() → asy::Stream<core::bool>
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<core::bool>;
+ function test3() → core::bool
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+ function test4() → asy::Stream<core::bool> /* originally async* */ {
+ asy::_AsyncStarStreamController<core::bool>? :controller;
+ dynamic :controller_stream;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ dynamic :saved_try_context_var1;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try
+ try {
+ #L8:
+ {
+ if(:controller.{asy::_AsyncStarStreamController::addStream}(let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:38:12: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+ yield* getStreamNull(); // error
+ ^" in self::getStreamNull() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>))
+ return null;
+ else
+ [yield] null;
+ }
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+ }
+ finally {
+ :controller.{asy::_AsyncStarStreamController::close}();
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
+ :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+ return :controller_stream;
+ }
+ function test5() → asy::Stream<core::bool>
+ return let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:41:27: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+ Stream<bool> test5() => getStreamNull(); // error
+ ^" in self::getStreamNull() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+ function test6() → asy::Stream<core::bool>
+ return self::getStreamBool();
+ function test7() → asy::Stream<core::bool> /* originally async* */ {
+ asy::_AsyncStarStreamController<core::bool>? :controller;
+ dynamic :controller_stream;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ dynamic :saved_try_context_var1;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try
+ try {
+ #L9:
+ {
+ if(:controller.{asy::_AsyncStarStreamController::addStream}(self::getStreamBool()))
+ return null;
+ else
+ [yield] null;
+ }
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+ }
+ finally {
+ :controller.{asy::_AsyncStarStreamController::close}();
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
+ :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+ return :controller_stream;
+ }
+ asy::Stream<core::bool> var1 = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:49:5: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+ })(); // error
+ ^" in (() → asy::Stream<dynamic> /* originally async* */ {
+ asy::_AsyncStarStreamController<dynamic>? :controller;
+ dynamic :controller_stream;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ dynamic :saved_try_context_var1;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try
+ try {
+ #L10:
+ {
+ if(:controller.{asy::_AsyncStarStreamController::add}(self::getNull()))
+ return null;
+ else
+ [yield] null;
+ }
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+ }
+ finally {
+ :controller.{asy::_AsyncStarStreamController::close}();
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :controller = new asy::_AsyncStarStreamController::•<dynamic>(:async_op);
+ :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+ return :controller_stream;
+ }).call() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+ asy::Stream<core::bool> var2 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<core::bool>;
+ core::bool var3 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+ asy::Stream<core::bool> var4 = let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:54:5: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+ })(); // error
+ ^" in (() → asy::Stream<dynamic> /* originally async* */ {
+ asy::_AsyncStarStreamController<dynamic>? :controller;
+ dynamic :controller_stream;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ dynamic :saved_try_context_var1;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try
+ try {
+ #L11:
+ {
+ if(:controller.{asy::_AsyncStarStreamController::addStream}(self::getStreamNull()))
+ return null;
+ else
+ [yield] null;
+ }
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+ }
+ finally {
+ :controller.{asy::_AsyncStarStreamController::close}();
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :controller = new asy::_AsyncStarStreamController::•<dynamic>(:async_op);
+ :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+ return :controller_stream;
+ }).call() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+ asy::Stream<core::bool> var5 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:55:46: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+ Stream<bool> var5 = (() => getStreamNull())(); // error
+ ^" in (() → asy::Stream<dynamic> => self::getStreamNull()).call() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+ asy::Stream<core::bool> var6 = (() → asy::Stream<core::bool> => self::getStreamBool()).call();
+ asy::Stream<core::bool> var7 = (() → asy::Stream<core::bool> /* originally async* */ {
+ asy::_AsyncStarStreamController<core::bool>? :controller;
+ dynamic :controller_stream;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ dynamic :saved_try_context_var1;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try
+ try {
+ #L12:
+ {
+ if(:controller.{asy::_AsyncStarStreamController::addStream}(self::getStreamBool()))
+ return null;
+ else
+ [yield] null;
+ }
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+ }
+ finally {
+ :controller.{asy::_AsyncStarStreamController::close}();
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
+ :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+ return :controller_stream;
+ }).call();
+ }
+ asy::_completeOnAsyncReturn(:async_completer, :return_value);
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+ return :async_completer.{asy::Completer::future};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41437c.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41437c.dart.weak.expect
new file mode 100644
index 0000000..16b4fb1
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41437c.dart.weak.expect
@@ -0,0 +1,122 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:21:10: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+// - 'Stream' is from 'dart:async'.
+// yield* getStreamNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:24:25: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+// - 'Stream' is from 'dart:async'.
+// Stream<bool> test5() => getStreamNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:38:12: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+// - 'Stream' is from 'dart:async'.
+// yield* getStreamNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:41:27: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+// - 'Stream' is from 'dart:async'.
+// Stream<bool> test5() => getStreamNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:49:5: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+// - 'Stream' is from 'dart:async'.
+// })(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:54:5: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+// - 'Stream' is from 'dart:async'.
+// })(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:55:46: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+// - 'Stream' is from 'dart:async'.
+// Stream<bool> var5 = (() => getStreamNull())(); // error
+// ^
+//
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method getNull() → dynamic
+ return null;
+static method getStreamNull() → asy::Stream<dynamic> async* {
+ yield null;
+}
+static method getStreamBool() → asy::Stream<core::bool> async* {
+ yield true;
+}
+static method test1() → asy::Stream<core::bool> async* {
+ yield self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+}
+static method test2() → asy::Stream<core::bool>
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<core::bool>;
+static method test3() → core::bool
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+static method test4() → asy::Stream<core::bool> async* {
+ yield* let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:21:10: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+ yield* getStreamNull(); // error
+ ^" in self::getStreamNull() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+}
+static method test5() → asy::Stream<core::bool>
+ return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:24:25: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+Stream<bool> test5() => getStreamNull(); // error
+ ^" in self::getStreamNull() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+static method test6() → asy::Stream<core::bool>
+ return self::getStreamBool();
+static method test7() → asy::Stream<core::bool> async* {
+ yield* self::getStreamBool();
+}
+static method test() → dynamic async {
+ function test1() → asy::Stream<core::bool> async* {
+ yield self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+ }
+ function test2() → asy::Stream<core::bool>
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<core::bool>;
+ function test3() → core::bool
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+ function test4() → asy::Stream<core::bool> async* {
+ yield* let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:38:12: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+ yield* getStreamNull(); // error
+ ^" in self::getStreamNull() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+ }
+ function test5() → asy::Stream<core::bool>
+ return let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:41:27: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+ Stream<bool> test5() => getStreamNull(); // error
+ ^" in self::getStreamNull() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+ function test6() → asy::Stream<core::bool>
+ return self::getStreamBool();
+ function test7() → asy::Stream<core::bool> async* {
+ yield* self::getStreamBool();
+ }
+ asy::Stream<core::bool> var1 = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:49:5: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+ })(); // error
+ ^" in (() → asy::Stream<dynamic> async* {
+ yield self::getNull();
+ }).call() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+ asy::Stream<core::bool> var2 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<core::bool>;
+ core::bool var3 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+ asy::Stream<core::bool> var4 = let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:54:5: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+ })(); // error
+ ^" in (() → asy::Stream<dynamic> async* {
+ yield* self::getStreamNull();
+ }).call() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+ asy::Stream<core::bool> var5 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:55:46: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+ Stream<bool> var5 = (() => getStreamNull())(); // error
+ ^" in (() → asy::Stream<dynamic> => self::getStreamNull()).call() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+ asy::Stream<core::bool> var6 = (() → asy::Stream<core::bool> => self::getStreamBool()).call();
+ asy::Stream<core::bool> var7 = (() → asy::Stream<core::bool> async* {
+ yield* self::getStreamBool();
+ }).call();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41437c.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41437c.dart.weak.transformed.expect
new file mode 100644
index 0000000..26e901c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41437c.dart.weak.transformed.expect
@@ -0,0 +1,497 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:21:10: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+// - 'Stream' is from 'dart:async'.
+// yield* getStreamNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:24:25: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+// - 'Stream' is from 'dart:async'.
+// Stream<bool> test5() => getStreamNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:38:12: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+// - 'Stream' is from 'dart:async'.
+// yield* getStreamNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:41:27: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+// - 'Stream' is from 'dart:async'.
+// Stream<bool> test5() => getStreamNull(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:49:5: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+// - 'Stream' is from 'dart:async'.
+// })(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:54:5: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+// - 'Stream' is from 'dart:async'.
+// })(); // error
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41437c.dart:55:46: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+// - 'Stream' is from 'dart:async'.
+// Stream<bool> var5 = (() => getStreamNull())(); // error
+// ^
+//
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method getNull() → dynamic
+ return null;
+static method getStreamNull() → asy::Stream<dynamic> /* originally async* */ {
+ asy::_AsyncStarStreamController<dynamic>? :controller;
+ dynamic :controller_stream;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ dynamic :saved_try_context_var1;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try
+ try {
+ #L1:
+ {
+ if(:controller.{asy::_AsyncStarStreamController::add}(null))
+ return null;
+ else
+ [yield] null;
+ }
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+ }
+ finally {
+ :controller.{asy::_AsyncStarStreamController::close}();
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :controller = new asy::_AsyncStarStreamController::•<dynamic>(:async_op);
+ :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+ return :controller_stream;
+}
+static method getStreamBool() → asy::Stream<core::bool> /* originally async* */ {
+ asy::_AsyncStarStreamController<core::bool>? :controller;
+ dynamic :controller_stream;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ dynamic :saved_try_context_var1;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try
+ try {
+ #L2:
+ {
+ if(:controller.{asy::_AsyncStarStreamController::add}(true))
+ return null;
+ else
+ [yield] null;
+ }
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+ }
+ finally {
+ :controller.{asy::_AsyncStarStreamController::close}();
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
+ :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+ return :controller_stream;
+}
+static method test1() → asy::Stream<core::bool> /* originally async* */ {
+ asy::_AsyncStarStreamController<core::bool>? :controller;
+ dynamic :controller_stream;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ dynamic :saved_try_context_var1;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try
+ try {
+ #L3:
+ {
+ if(:controller.{asy::_AsyncStarStreamController::add}(self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool))
+ return null;
+ else
+ [yield] null;
+ }
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+ }
+ finally {
+ :controller.{asy::_AsyncStarStreamController::close}();
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
+ :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+ return :controller_stream;
+}
+static method test2() → asy::Stream<core::bool>
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<core::bool>;
+static method test3() → core::bool
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+static method test4() → asy::Stream<core::bool> /* originally async* */ {
+ asy::_AsyncStarStreamController<core::bool>? :controller;
+ dynamic :controller_stream;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ dynamic :saved_try_context_var1;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try
+ try {
+ #L4:
+ {
+ if(:controller.{asy::_AsyncStarStreamController::addStream}(let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:21:10: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+ yield* getStreamNull(); // error
+ ^" in self::getStreamNull() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>))
+ return null;
+ else
+ [yield] null;
+ }
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+ }
+ finally {
+ :controller.{asy::_AsyncStarStreamController::close}();
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
+ :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+ return :controller_stream;
+}
+static method test5() → asy::Stream<core::bool>
+ return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:24:25: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+Stream<bool> test5() => getStreamNull(); // error
+ ^" in self::getStreamNull() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+static method test6() → asy::Stream<core::bool>
+ return self::getStreamBool();
+static method test7() → asy::Stream<core::bool> /* originally async* */ {
+ asy::_AsyncStarStreamController<core::bool>? :controller;
+ dynamic :controller_stream;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ dynamic :saved_try_context_var1;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try
+ try {
+ #L5:
+ {
+ if(:controller.{asy::_AsyncStarStreamController::addStream}(self::getStreamBool()))
+ return null;
+ else
+ [yield] null;
+ }
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+ }
+ finally {
+ :controller.{asy::_AsyncStarStreamController::close}();
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
+ :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+ return :controller_stream;
+}
+static method test() → dynamic /* originally async */ {
+ final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+ asy::FutureOr<dynamic>? :return_value;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L6:
+ {
+ function test1() → asy::Stream<core::bool> /* originally async* */ {
+ asy::_AsyncStarStreamController<core::bool>? :controller;
+ dynamic :controller_stream;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ dynamic :saved_try_context_var1;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try
+ try {
+ #L7:
+ {
+ if(:controller.{asy::_AsyncStarStreamController::add}(self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool))
+ return null;
+ else
+ [yield] null;
+ }
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+ }
+ finally {
+ :controller.{asy::_AsyncStarStreamController::close}();
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
+ :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+ return :controller_stream;
+ }
+ function test2() → asy::Stream<core::bool>
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<core::bool>;
+ function test3() → core::bool
+ return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+ function test4() → asy::Stream<core::bool> /* originally async* */ {
+ asy::_AsyncStarStreamController<core::bool>? :controller;
+ dynamic :controller_stream;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ dynamic :saved_try_context_var1;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try
+ try {
+ #L8:
+ {
+ if(:controller.{asy::_AsyncStarStreamController::addStream}(let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:38:12: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+ yield* getStreamNull(); // error
+ ^" in self::getStreamNull() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>))
+ return null;
+ else
+ [yield] null;
+ }
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+ }
+ finally {
+ :controller.{asy::_AsyncStarStreamController::close}();
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
+ :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+ return :controller_stream;
+ }
+ function test5() → asy::Stream<core::bool>
+ return let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:41:27: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+ Stream<bool> test5() => getStreamNull(); // error
+ ^" in self::getStreamNull() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+ function test6() → asy::Stream<core::bool>
+ return self::getStreamBool();
+ function test7() → asy::Stream<core::bool> /* originally async* */ {
+ asy::_AsyncStarStreamController<core::bool>? :controller;
+ dynamic :controller_stream;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ dynamic :saved_try_context_var1;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try
+ try {
+ #L9:
+ {
+ if(:controller.{asy::_AsyncStarStreamController::addStream}(self::getStreamBool()))
+ return null;
+ else
+ [yield] null;
+ }
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+ }
+ finally {
+ :controller.{asy::_AsyncStarStreamController::close}();
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
+ :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+ return :controller_stream;
+ }
+ asy::Stream<core::bool> var1 = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:49:5: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+ })(); // error
+ ^" in (() → asy::Stream<dynamic> /* originally async* */ {
+ asy::_AsyncStarStreamController<dynamic>? :controller;
+ dynamic :controller_stream;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ dynamic :saved_try_context_var1;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try
+ try {
+ #L10:
+ {
+ if(:controller.{asy::_AsyncStarStreamController::add}(self::getNull()))
+ return null;
+ else
+ [yield] null;
+ }
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+ }
+ finally {
+ :controller.{asy::_AsyncStarStreamController::close}();
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :controller = new asy::_AsyncStarStreamController::•<dynamic>(:async_op);
+ :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+ return :controller_stream;
+ }).call() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+ asy::Stream<core::bool> var2 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<core::bool>;
+ core::bool var3 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
+ asy::Stream<core::bool> var4 = let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:54:5: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+ })(); // error
+ ^" in (() → asy::Stream<dynamic> /* originally async* */ {
+ asy::_AsyncStarStreamController<dynamic>? :controller;
+ dynamic :controller_stream;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ dynamic :saved_try_context_var1;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try
+ try {
+ #L11:
+ {
+ if(:controller.{asy::_AsyncStarStreamController::addStream}(self::getStreamNull()))
+ return null;
+ else
+ [yield] null;
+ }
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+ }
+ finally {
+ :controller.{asy::_AsyncStarStreamController::close}();
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :controller = new asy::_AsyncStarStreamController::•<dynamic>(:async_op);
+ :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+ return :controller_stream;
+ }).call() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+ asy::Stream<core::bool> var5 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437c.dart:55:46: Error: A value of type 'Stream<dynamic>' can't be assigned to a variable of type 'Stream<bool>'.
+ - 'Stream' is from 'dart:async'.
+ Stream<bool> var5 = (() => getStreamNull())(); // error
+ ^" in (() → asy::Stream<dynamic> => self::getStreamNull()).call() as{TypeError,ForNonNullableByDefault} asy::Stream<core::bool>;
+ asy::Stream<core::bool> var6 = (() → asy::Stream<core::bool> => self::getStreamBool()).call();
+ asy::Stream<core::bool> var7 = (() → asy::Stream<core::bool> /* originally async* */ {
+ asy::_AsyncStarStreamController<core::bool>? :controller;
+ dynamic :controller_stream;
+ dynamic :async_stack_trace;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ dynamic :saved_try_context_var1;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try
+ try {
+ #L12:
+ {
+ if(:controller.{asy::_AsyncStarStreamController::addStream}(self::getStreamBool()))
+ return null;
+ else
+ [yield] null;
+ }
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+ }
+ finally {
+ :controller.{asy::_AsyncStarStreamController::close}();
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :controller = new asy::_AsyncStarStreamController::•<core::bool>(:async_op);
+ :controller_stream = :controller.{asy::_AsyncStarStreamController::stream};
+ return :controller_stream;
+ }).call();
+ }
+ asy::_completeOnAsyncReturn(:async_completer, :return_value);
+ return;
+ }
+ on dynamic catch(dynamic :exception, core::StackTrace :stack_trace) {
+ :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+ }
+ :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
+ return :async_completer.{asy::Completer::future};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41495.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue41495.dart.textual_outline.expect
new file mode 100644
index 0000000..b1feffb
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41495.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class A {
+ int c1 = 1;
+ int test() => 2;
+}
+
+main() {}
+errors() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41495.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue41495.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..faa0d89
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41495.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class A {
+ int c1 = 1;
+ int test() => 2;
+}
+
+errors() {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41496.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue41496.dart.textual_outline.expect
new file mode 100644
index 0000000..bab3915
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41496.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+import "issue41496_lib.dart";
+
+LegacyFoo f1;
+
+class C {
+ static LegacyFoo f2;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41496.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue41496.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bab3915
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41496.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+import "issue41496_lib.dart";
+
+LegacyFoo f1;
+
+class C {
+ static LegacyFoo f2;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41496b.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue41496b.dart.textual_outline.expect
new file mode 100644
index 0000000..d47c066
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41496b.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+library opted_out_lib;
+
+import 'issue41496b_lib.dart' as opt_in;
+
+typedef void LegacyFoo();
+test(LegacyFoo f) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41496b.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue41496b.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..40de3a0
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41496b.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+// @dart = 2.6
+library opted_out_lib;
+
+import 'issue41496b_lib.dart' as opt_in;
+
+main() {}
+test(LegacyFoo f) {}
+typedef void LegacyFoo();
diff --git a/pkg/front_end/testcases/nnbd/issue41498.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue41498.dart.textual_outline.expect
new file mode 100644
index 0000000..843b73c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41498.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+import "issue41498_lib.dart";
+
+class C {
+ static void test() {}
+ void test2() {}
+}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41498.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue41498.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a871709
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41498.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+import "issue41498_lib.dart";
+
+class C {
+ static void test() {}
+ void test2() {}
+}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41498b.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue41498b.dart.textual_outline.expect
new file mode 100644
index 0000000..6ad2a78
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41498b.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+// @dart = 2.6
+library opted_out_lib;
+
+import 'issue41498b_lib.dart' as opt_in;
+
+typedef void LegacyFoo();
+
+class C {
+ static void test() {}
+ void test2() {}
+}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41498b.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue41498b.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..17f71c7
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41498b.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+// @dart = 2.6
+library opted_out_lib;
+
+import 'issue41498b_lib.dart' as opt_in;
+
+class C {
+ static void test() {}
+ void test2() {}
+}
+
+main() {}
+test() {}
+typedef void LegacyFoo();
diff --git a/pkg/front_end/testcases/nnbd/issue41499.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue41499.dart.textual_outline.expect
new file mode 100644
index 0000000..040ccd2
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41499.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+import "issue41499_lib.dart";
+
+class C {
+ static LegacyFoo sTest() {}
+ LegacyFoo mTest() {}
+ LegacyFoo get gTest {}
+}
+
+LegacyFoo test() {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41499.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue41499.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7d62fe6
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41499.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+import "issue41499_lib.dart";
+
+LegacyFoo test() {}
+
+class C {
+ LegacyFoo get gTest {}
+ LegacyFoo mTest() {}
+ static LegacyFoo sTest() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41499b.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue41499b.dart.textual_outline.expect
new file mode 100644
index 0000000..f853f4d
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41499b.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'issue41499b_lib.dart' as opt_in;
+
+typedef void LegacyFoo();
+test(LegacyFoo f) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41499b.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue41499b.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ae7272f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41499b.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'issue41499b_lib.dart' as opt_in;
+
+main() {}
+test(LegacyFoo f) {}
+typedef void LegacyFoo();
diff --git a/pkg/front_end/testcases/nnbd/issue41567.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue41567.dart.textual_outline.expect
new file mode 100644
index 0000000..4a39bd7
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41567.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+import 'issue41567_lib.dart';
+
+class B extends A {}
+
+class in1 extends out_Object implements B {}
+
+class in2 extends B implements out_Object {}
+
+class in3 extends out_int implements B {}
+
+class in4 extends B implements out_int {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41567.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue41567.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4a39bd7
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41567.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+import 'issue41567_lib.dart';
+
+class B extends A {}
+
+class in1 extends out_Object implements B {}
+
+class in2 extends B implements out_Object {}
+
+class in3 extends out_int implements B {}
+
+class in4 extends B implements out_int {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41597.dart b/pkg/front_end/testcases/nnbd/issue41597.dart
new file mode 100644
index 0000000..0180159
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41597.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'issue41597_lib.dart';
+
+bool x;
+bool x;
+
+errors() {
+ print(x);
+ print(x!);
+ print(!x);
+}
+
+class C {
+ C.c0() : super();
+ C.c1() : super()!;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41597.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue41597.dart.outline.expect
new file mode 100644
index 0000000..6a4719a
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41597.dart.outline.expect
@@ -0,0 +1,41 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:8:6: Error: 'x' is already declared in this scope.
+// bool x;
+// ^
+// pkg/front_end/testcases/nnbd/issue41597.dart:7:6: Context: Previous declaration of 'x'.
+// bool x;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:8:6: Error: Field 'x' should be initialized because its type 'bool' doesn't allow null.
+// bool x;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:7:6: Error: Field 'x' should be initialized because its type 'bool' doesn't allow null.
+// bool x;
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41597_lib.dart";
+
+class C extends core::Object {
+ constructor c0() → self::C
+ ;
+ constructor c1() → self::C
+ ;
+}
+static field core::bool x;
+static method errors() → dynamic
+ ;
+static method main() → dynamic
+ ;
+
+library;
+import self as self2;
+
+static method errors(dynamic c) → dynamic
+ ;
diff --git a/pkg/front_end/testcases/nnbd/issue41597.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41597.dart.strong.expect
new file mode 100644
index 0000000..e5736ef
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41597.dart.strong.expect
@@ -0,0 +1,120 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:8:6: Error: 'x' is already declared in this scope.
+// bool x;
+// ^
+// pkg/front_end/testcases/nnbd/issue41597.dart:7:6: Context: Previous declaration of 'x'.
+// bool x;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:8:6: Error: Field 'x' should be initialized because its type 'bool' doesn't allow null.
+// bool x;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:7:6: Error: Field 'x' should be initialized because its type 'bool' doesn't allow null.
+// bool x;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:11:9: Error: Can't use 'x' because it is declared more than once.
+// print(x);
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:12:9: Error: Can't use 'x' because it is declared more than once.
+// print(x!);
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:13:10: Error: Can't use 'x' because it is declared more than once.
+// print(!x);
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:18:12: Error: Can't use 'super' as an expression.
+// To delegate a constructor to a super constructor, put the super call as an initializer.
+// C.c1() : super()!;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:18:19: Error: Expected an initializer.
+// C.c1() : super()!;
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41597_lib.dart";
+
+class C extends core::Object {
+ constructor c0() → self::C
+ : super core::Object::•()
+ ;
+ constructor c1() → self::C
+ : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41597.dart:18:12: Error: Can't use 'super' as an expression.
+To delegate a constructor to a super constructor, put the super call as an initializer.
+ C.c1() : super()!;
+ ^"!
+ ;
+}
+static field core::bool x;
+static method errors() → dynamic {
+ core::print(invalid-expression "pkg/front_end/testcases/nnbd/issue41597.dart:11:9: Error: Can't use 'x' because it is declared more than once.
+ print(x);
+ ^");
+ core::print(invalid-expression "pkg/front_end/testcases/nnbd/issue41597.dart:12:9: Error: Can't use 'x' because it is declared more than once.
+ print(x!);
+ ^"!);
+ core::print(!(invalid-expression "pkg/front_end/testcases/nnbd/issue41597.dart:13:10: Error: Can't use 'x' because it is declared more than once.
+ print(!x);
+ ^" as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool));
+}
+static method main() → dynamic {}
+
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:8:6: Error: Expected an identifier, but got '.'.
+// c?..f;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:8:6: Error: Expected an identifier, but got ''.
+// c?..f;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:9:7: Error: Expected an identifier, but got '.'.
+// !c?..f;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:9:7: Error: Expected an identifier, but got ''.
+// !c?..f;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:10:6: Error: Expected an identifier, but got '.'.
+// c?..f!;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:10:6: Error: Expected an identifier, but got ''.
+// c?..f!;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:10:8: Error: Null safety features are disabled for this library.
+// Try removing the `@dart=` annotation or setting the language version higher.
+// c?..f!;
+// ^
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
+// // @dart=2.6
+// ^^^^^^^^^^^^
+//
+import self as self2;
+import "dart:core" as core;
+
+static method errors(dynamic c) → dynamic {
+ invalid-expression "pkg/front_end/testcases/nnbd/issue41597_lib.dart:8:6: Error: Expected an identifier, but got ''.
+ c?..f;
+ ^".f;
+ !(invalid-expression "pkg/front_end/testcases/nnbd/issue41597_lib.dart:9:7: Error: Expected an identifier, but got ''.
+ !c?..f;
+ ^".f as{TypeError,ForDynamic} core::bool*);
+ invalid-expression "pkg/front_end/testcases/nnbd/issue41597_lib.dart:10:6: Error: Expected an identifier, but got ''.
+ c?..f!;
+ ^".f!;
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41597.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41597.dart.strong.transformed.expect
new file mode 100644
index 0000000..e5736ef
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41597.dart.strong.transformed.expect
@@ -0,0 +1,120 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:8:6: Error: 'x' is already declared in this scope.
+// bool x;
+// ^
+// pkg/front_end/testcases/nnbd/issue41597.dart:7:6: Context: Previous declaration of 'x'.
+// bool x;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:8:6: Error: Field 'x' should be initialized because its type 'bool' doesn't allow null.
+// bool x;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:7:6: Error: Field 'x' should be initialized because its type 'bool' doesn't allow null.
+// bool x;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:11:9: Error: Can't use 'x' because it is declared more than once.
+// print(x);
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:12:9: Error: Can't use 'x' because it is declared more than once.
+// print(x!);
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:13:10: Error: Can't use 'x' because it is declared more than once.
+// print(!x);
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:18:12: Error: Can't use 'super' as an expression.
+// To delegate a constructor to a super constructor, put the super call as an initializer.
+// C.c1() : super()!;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:18:19: Error: Expected an initializer.
+// C.c1() : super()!;
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41597_lib.dart";
+
+class C extends core::Object {
+ constructor c0() → self::C
+ : super core::Object::•()
+ ;
+ constructor c1() → self::C
+ : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41597.dart:18:12: Error: Can't use 'super' as an expression.
+To delegate a constructor to a super constructor, put the super call as an initializer.
+ C.c1() : super()!;
+ ^"!
+ ;
+}
+static field core::bool x;
+static method errors() → dynamic {
+ core::print(invalid-expression "pkg/front_end/testcases/nnbd/issue41597.dart:11:9: Error: Can't use 'x' because it is declared more than once.
+ print(x);
+ ^");
+ core::print(invalid-expression "pkg/front_end/testcases/nnbd/issue41597.dart:12:9: Error: Can't use 'x' because it is declared more than once.
+ print(x!);
+ ^"!);
+ core::print(!(invalid-expression "pkg/front_end/testcases/nnbd/issue41597.dart:13:10: Error: Can't use 'x' because it is declared more than once.
+ print(!x);
+ ^" as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool));
+}
+static method main() → dynamic {}
+
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:8:6: Error: Expected an identifier, but got '.'.
+// c?..f;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:8:6: Error: Expected an identifier, but got ''.
+// c?..f;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:9:7: Error: Expected an identifier, but got '.'.
+// !c?..f;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:9:7: Error: Expected an identifier, but got ''.
+// !c?..f;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:10:6: Error: Expected an identifier, but got '.'.
+// c?..f!;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:10:6: Error: Expected an identifier, but got ''.
+// c?..f!;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:10:8: Error: Null safety features are disabled for this library.
+// Try removing the `@dart=` annotation or setting the language version higher.
+// c?..f!;
+// ^
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
+// // @dart=2.6
+// ^^^^^^^^^^^^
+//
+import self as self2;
+import "dart:core" as core;
+
+static method errors(dynamic c) → dynamic {
+ invalid-expression "pkg/front_end/testcases/nnbd/issue41597_lib.dart:8:6: Error: Expected an identifier, but got ''.
+ c?..f;
+ ^".f;
+ !(invalid-expression "pkg/front_end/testcases/nnbd/issue41597_lib.dart:9:7: Error: Expected an identifier, but got ''.
+ !c?..f;
+ ^".f as{TypeError,ForDynamic} core::bool*);
+ invalid-expression "pkg/front_end/testcases/nnbd/issue41597_lib.dart:10:6: Error: Expected an identifier, but got ''.
+ c?..f!;
+ ^".f!;
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41597.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue41597.dart.textual_outline.expect
new file mode 100644
index 0000000..792707c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41597.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+import 'issue41597_lib.dart';
+bool x;
+bool x;
+errors() { }
+class C {
+ C.c0() : super();
+ C.c1() : super()!;
+}
+main() { }
diff --git a/pkg/front_end/testcases/nnbd/issue41597.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41597.dart.weak.expect
new file mode 100644
index 0000000..e5736ef
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41597.dart.weak.expect
@@ -0,0 +1,120 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:8:6: Error: 'x' is already declared in this scope.
+// bool x;
+// ^
+// pkg/front_end/testcases/nnbd/issue41597.dart:7:6: Context: Previous declaration of 'x'.
+// bool x;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:8:6: Error: Field 'x' should be initialized because its type 'bool' doesn't allow null.
+// bool x;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:7:6: Error: Field 'x' should be initialized because its type 'bool' doesn't allow null.
+// bool x;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:11:9: Error: Can't use 'x' because it is declared more than once.
+// print(x);
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:12:9: Error: Can't use 'x' because it is declared more than once.
+// print(x!);
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:13:10: Error: Can't use 'x' because it is declared more than once.
+// print(!x);
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:18:12: Error: Can't use 'super' as an expression.
+// To delegate a constructor to a super constructor, put the super call as an initializer.
+// C.c1() : super()!;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:18:19: Error: Expected an initializer.
+// C.c1() : super()!;
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41597_lib.dart";
+
+class C extends core::Object {
+ constructor c0() → self::C
+ : super core::Object::•()
+ ;
+ constructor c1() → self::C
+ : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41597.dart:18:12: Error: Can't use 'super' as an expression.
+To delegate a constructor to a super constructor, put the super call as an initializer.
+ C.c1() : super()!;
+ ^"!
+ ;
+}
+static field core::bool x;
+static method errors() → dynamic {
+ core::print(invalid-expression "pkg/front_end/testcases/nnbd/issue41597.dart:11:9: Error: Can't use 'x' because it is declared more than once.
+ print(x);
+ ^");
+ core::print(invalid-expression "pkg/front_end/testcases/nnbd/issue41597.dart:12:9: Error: Can't use 'x' because it is declared more than once.
+ print(x!);
+ ^"!);
+ core::print(!(invalid-expression "pkg/front_end/testcases/nnbd/issue41597.dart:13:10: Error: Can't use 'x' because it is declared more than once.
+ print(!x);
+ ^" as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool));
+}
+static method main() → dynamic {}
+
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:8:6: Error: Expected an identifier, but got '.'.
+// c?..f;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:8:6: Error: Expected an identifier, but got ''.
+// c?..f;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:9:7: Error: Expected an identifier, but got '.'.
+// !c?..f;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:9:7: Error: Expected an identifier, but got ''.
+// !c?..f;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:10:6: Error: Expected an identifier, but got '.'.
+// c?..f!;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:10:6: Error: Expected an identifier, but got ''.
+// c?..f!;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:10:8: Error: Null safety features are disabled for this library.
+// Try removing the `@dart=` annotation or setting the language version higher.
+// c?..f!;
+// ^
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
+// // @dart=2.6
+// ^^^^^^^^^^^^
+//
+import self as self2;
+import "dart:core" as core;
+
+static method errors(dynamic c) → dynamic {
+ invalid-expression "pkg/front_end/testcases/nnbd/issue41597_lib.dart:8:6: Error: Expected an identifier, but got ''.
+ c?..f;
+ ^".f;
+ !(invalid-expression "pkg/front_end/testcases/nnbd/issue41597_lib.dart:9:7: Error: Expected an identifier, but got ''.
+ !c?..f;
+ ^".f as{TypeError,ForDynamic} core::bool*);
+ invalid-expression "pkg/front_end/testcases/nnbd/issue41597_lib.dart:10:6: Error: Expected an identifier, but got ''.
+ c?..f!;
+ ^".f!;
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41597.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41597.dart.weak.transformed.expect
new file mode 100644
index 0000000..e5736ef
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41597.dart.weak.transformed.expect
@@ -0,0 +1,120 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:8:6: Error: 'x' is already declared in this scope.
+// bool x;
+// ^
+// pkg/front_end/testcases/nnbd/issue41597.dart:7:6: Context: Previous declaration of 'x'.
+// bool x;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:8:6: Error: Field 'x' should be initialized because its type 'bool' doesn't allow null.
+// bool x;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:7:6: Error: Field 'x' should be initialized because its type 'bool' doesn't allow null.
+// bool x;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:11:9: Error: Can't use 'x' because it is declared more than once.
+// print(x);
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:12:9: Error: Can't use 'x' because it is declared more than once.
+// print(x!);
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:13:10: Error: Can't use 'x' because it is declared more than once.
+// print(!x);
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:18:12: Error: Can't use 'super' as an expression.
+// To delegate a constructor to a super constructor, put the super call as an initializer.
+// C.c1() : super()!;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597.dart:18:19: Error: Expected an initializer.
+// C.c1() : super()!;
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue41597_lib.dart";
+
+class C extends core::Object {
+ constructor c0() → self::C
+ : super core::Object::•()
+ ;
+ constructor c1() → self::C
+ : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41597.dart:18:12: Error: Can't use 'super' as an expression.
+To delegate a constructor to a super constructor, put the super call as an initializer.
+ C.c1() : super()!;
+ ^"!
+ ;
+}
+static field core::bool x;
+static method errors() → dynamic {
+ core::print(invalid-expression "pkg/front_end/testcases/nnbd/issue41597.dart:11:9: Error: Can't use 'x' because it is declared more than once.
+ print(x);
+ ^");
+ core::print(invalid-expression "pkg/front_end/testcases/nnbd/issue41597.dart:12:9: Error: Can't use 'x' because it is declared more than once.
+ print(x!);
+ ^"!);
+ core::print(!(invalid-expression "pkg/front_end/testcases/nnbd/issue41597.dart:13:10: Error: Can't use 'x' because it is declared more than once.
+ print(!x);
+ ^" as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool));
+}
+static method main() → dynamic {}
+
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:8:6: Error: Expected an identifier, but got '.'.
+// c?..f;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:8:6: Error: Expected an identifier, but got ''.
+// c?..f;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:9:7: Error: Expected an identifier, but got '.'.
+// !c?..f;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:9:7: Error: Expected an identifier, but got ''.
+// !c?..f;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:10:6: Error: Expected an identifier, but got '.'.
+// c?..f!;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:10:6: Error: Expected an identifier, but got ''.
+// c?..f!;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:10:8: Error: Null safety features are disabled for this library.
+// Try removing the `@dart=` annotation or setting the language version higher.
+// c?..f!;
+// ^
+// pkg/front_end/testcases/nnbd/issue41597_lib.dart:5:1: Context: This is the annotation that opts out this library from null safety features.
+// // @dart=2.6
+// ^^^^^^^^^^^^
+//
+import self as self2;
+import "dart:core" as core;
+
+static method errors(dynamic c) → dynamic {
+ invalid-expression "pkg/front_end/testcases/nnbd/issue41597_lib.dart:8:6: Error: Expected an identifier, but got ''.
+ c?..f;
+ ^".f;
+ !(invalid-expression "pkg/front_end/testcases/nnbd/issue41597_lib.dart:9:7: Error: Expected an identifier, but got ''.
+ !c?..f;
+ ^".f as{TypeError,ForDynamic} core::bool*);
+ invalid-expression "pkg/front_end/testcases/nnbd/issue41597_lib.dart:10:6: Error: Expected an identifier, but got ''.
+ c?..f!;
+ ^".f!;
+}
diff --git a/pkg/front_end/testcases/nnbd/issue41597_lib.dart b/pkg/front_end/testcases/nnbd/issue41597_lib.dart
new file mode 100644
index 0000000..b810fd8
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41597_lib.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart=2.6
+
+errors(c) {
+ c?..f;
+ !c?..f;
+ c?..f!;
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/nnbd/issue41700a.dart b/pkg/front_end/testcases/nnbd/issue41700a.dart
new file mode 100644
index 0000000..d04ab3e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41700a.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+test() {
+ Null x = null;
+ x.foo();
+ Null? y = null;
+ y.foo();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41700a.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue41700a.dart.outline.expect
new file mode 100644
index 0000000..64923de
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41700a.dart.outline.expect
@@ -0,0 +1,7 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+static method test() → dynamic
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/nnbd/issue41700a.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41700a.dart.strong.expect
new file mode 100644
index 0000000..65b8b25
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41700a.dart.strong.expect
@@ -0,0 +1,30 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41700a.dart:7:5: Error: The method 'foo' isn't defined for the class 'Null'.
+// Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+// x.foo();
+// ^^^
+//
+// pkg/front_end/testcases/nnbd/issue41700a.dart:9:5: Error: The method 'foo' isn't defined for the class 'Null'.
+// Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+// y.foo();
+// ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+static method test() → dynamic {
+ core::Null? x = null;
+ invalid-expression "pkg/front_end/testcases/nnbd/issue41700a.dart:7:5: Error: The method 'foo' isn't defined for the class 'Null'.
+Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+ x.foo();
+ ^^^";
+ core::Null? y = null;
+ invalid-expression "pkg/front_end/testcases/nnbd/issue41700a.dart:9:5: Error: The method 'foo' isn't defined for the class 'Null'.
+Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+ y.foo();
+ ^^^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41700a.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41700a.dart.strong.transformed.expect
new file mode 100644
index 0000000..65b8b25
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41700a.dart.strong.transformed.expect
@@ -0,0 +1,30 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41700a.dart:7:5: Error: The method 'foo' isn't defined for the class 'Null'.
+// Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+// x.foo();
+// ^^^
+//
+// pkg/front_end/testcases/nnbd/issue41700a.dart:9:5: Error: The method 'foo' isn't defined for the class 'Null'.
+// Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+// y.foo();
+// ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+static method test() → dynamic {
+ core::Null? x = null;
+ invalid-expression "pkg/front_end/testcases/nnbd/issue41700a.dart:7:5: Error: The method 'foo' isn't defined for the class 'Null'.
+Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+ x.foo();
+ ^^^";
+ core::Null? y = null;
+ invalid-expression "pkg/front_end/testcases/nnbd/issue41700a.dart:9:5: Error: The method 'foo' isn't defined for the class 'Null'.
+Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+ y.foo();
+ ^^^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41700a.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41700a.dart.weak.expect
new file mode 100644
index 0000000..65b8b25
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41700a.dart.weak.expect
@@ -0,0 +1,30 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41700a.dart:7:5: Error: The method 'foo' isn't defined for the class 'Null'.
+// Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+// x.foo();
+// ^^^
+//
+// pkg/front_end/testcases/nnbd/issue41700a.dart:9:5: Error: The method 'foo' isn't defined for the class 'Null'.
+// Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+// y.foo();
+// ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+static method test() → dynamic {
+ core::Null? x = null;
+ invalid-expression "pkg/front_end/testcases/nnbd/issue41700a.dart:7:5: Error: The method 'foo' isn't defined for the class 'Null'.
+Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+ x.foo();
+ ^^^";
+ core::Null? y = null;
+ invalid-expression "pkg/front_end/testcases/nnbd/issue41700a.dart:9:5: Error: The method 'foo' isn't defined for the class 'Null'.
+Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+ y.foo();
+ ^^^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41700a.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41700a.dart.weak.transformed.expect
new file mode 100644
index 0000000..65b8b25
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41700a.dart.weak.transformed.expect
@@ -0,0 +1,30 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41700a.dart:7:5: Error: The method 'foo' isn't defined for the class 'Null'.
+// Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+// x.foo();
+// ^^^
+//
+// pkg/front_end/testcases/nnbd/issue41700a.dart:9:5: Error: The method 'foo' isn't defined for the class 'Null'.
+// Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+// y.foo();
+// ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+static method test() → dynamic {
+ core::Null? x = null;
+ invalid-expression "pkg/front_end/testcases/nnbd/issue41700a.dart:7:5: Error: The method 'foo' isn't defined for the class 'Null'.
+Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+ x.foo();
+ ^^^";
+ core::Null? y = null;
+ invalid-expression "pkg/front_end/testcases/nnbd/issue41700a.dart:9:5: Error: The method 'foo' isn't defined for the class 'Null'.
+Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+ y.foo();
+ ^^^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41700b.dart b/pkg/front_end/testcases/nnbd/issue41700b.dart
new file mode 100644
index 0000000..5cc3693
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41700b.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class Null {}
+
+test() {
+ Null x = null;
+ x.foo();
+ Null? y = null;
+ y.foo();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue41700b.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue41700b.dart.outline.expect
new file mode 100644
index 0000000..2e0425c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41700b.dart.outline.expect
@@ -0,0 +1,12 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Null extends core::Object {
+ synthetic constructor •() → self::Null
+ ;
+}
+static method test() → dynamic
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/nnbd/issue41700b.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41700b.dart.strong.expect
new file mode 100644
index 0000000..79e8633
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41700b.dart.strong.expect
@@ -0,0 +1,49 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41700b.dart:8:12: Error: A value of type 'Null/*1*/' can't be assigned to a variable of type 'Null/*2*/'.
+// - 'Null/*1*/' is from 'dart:core'.
+// - 'Null/*2*/' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+// Null x = null;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41700b.dart:9:5: Error: The method 'foo' isn't defined for the class 'Null'.
+// - 'Null' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+// Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+// x.foo();
+// ^^^
+//
+// pkg/front_end/testcases/nnbd/issue41700b.dart:11:5: Error: The method 'foo' isn't defined for the class 'Null?'.
+// - 'Null' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+// Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+// y.foo();
+// ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Null extends core::Object {
+ synthetic constructor •() → self::Null
+ : super core::Object::•()
+ ;
+}
+static method test() → dynamic {
+ self::Null x = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41700b.dart:8:12: Error: A value of type 'Null/*1*/' can't be assigned to a variable of type 'Null/*2*/'.
+ - 'Null/*1*/' is from 'dart:core'.
+ - 'Null/*2*/' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+ Null x = null;
+ ^" in null as{TypeError,ForNonNullableByDefault} self::Null;
+ invalid-expression "pkg/front_end/testcases/nnbd/issue41700b.dart:9:5: Error: The method 'foo' isn't defined for the class 'Null'.
+ - 'Null' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+ x.foo();
+ ^^^";
+ self::Null? y = null;
+ invalid-expression "pkg/front_end/testcases/nnbd/issue41700b.dart:11:5: Error: The method 'foo' isn't defined for the class 'Null?'.
+ - 'Null' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+ y.foo();
+ ^^^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41700b.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41700b.dart.strong.transformed.expect
new file mode 100644
index 0000000..79e8633
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41700b.dart.strong.transformed.expect
@@ -0,0 +1,49 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41700b.dart:8:12: Error: A value of type 'Null/*1*/' can't be assigned to a variable of type 'Null/*2*/'.
+// - 'Null/*1*/' is from 'dart:core'.
+// - 'Null/*2*/' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+// Null x = null;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41700b.dart:9:5: Error: The method 'foo' isn't defined for the class 'Null'.
+// - 'Null' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+// Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+// x.foo();
+// ^^^
+//
+// pkg/front_end/testcases/nnbd/issue41700b.dart:11:5: Error: The method 'foo' isn't defined for the class 'Null?'.
+// - 'Null' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+// Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+// y.foo();
+// ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Null extends core::Object {
+ synthetic constructor •() → self::Null
+ : super core::Object::•()
+ ;
+}
+static method test() → dynamic {
+ self::Null x = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41700b.dart:8:12: Error: A value of type 'Null/*1*/' can't be assigned to a variable of type 'Null/*2*/'.
+ - 'Null/*1*/' is from 'dart:core'.
+ - 'Null/*2*/' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+ Null x = null;
+ ^" in null as{TypeError,ForNonNullableByDefault} self::Null;
+ invalid-expression "pkg/front_end/testcases/nnbd/issue41700b.dart:9:5: Error: The method 'foo' isn't defined for the class 'Null'.
+ - 'Null' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+ x.foo();
+ ^^^";
+ self::Null? y = null;
+ invalid-expression "pkg/front_end/testcases/nnbd/issue41700b.dart:11:5: Error: The method 'foo' isn't defined for the class 'Null?'.
+ - 'Null' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+ y.foo();
+ ^^^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41700b.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41700b.dart.weak.expect
new file mode 100644
index 0000000..79e8633
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41700b.dart.weak.expect
@@ -0,0 +1,49 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41700b.dart:8:12: Error: A value of type 'Null/*1*/' can't be assigned to a variable of type 'Null/*2*/'.
+// - 'Null/*1*/' is from 'dart:core'.
+// - 'Null/*2*/' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+// Null x = null;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41700b.dart:9:5: Error: The method 'foo' isn't defined for the class 'Null'.
+// - 'Null' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+// Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+// x.foo();
+// ^^^
+//
+// pkg/front_end/testcases/nnbd/issue41700b.dart:11:5: Error: The method 'foo' isn't defined for the class 'Null?'.
+// - 'Null' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+// Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+// y.foo();
+// ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Null extends core::Object {
+ synthetic constructor •() → self::Null
+ : super core::Object::•()
+ ;
+}
+static method test() → dynamic {
+ self::Null x = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41700b.dart:8:12: Error: A value of type 'Null/*1*/' can't be assigned to a variable of type 'Null/*2*/'.
+ - 'Null/*1*/' is from 'dart:core'.
+ - 'Null/*2*/' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+ Null x = null;
+ ^" in null as{TypeError,ForNonNullableByDefault} self::Null;
+ invalid-expression "pkg/front_end/testcases/nnbd/issue41700b.dart:9:5: Error: The method 'foo' isn't defined for the class 'Null'.
+ - 'Null' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+ x.foo();
+ ^^^";
+ self::Null? y = null;
+ invalid-expression "pkg/front_end/testcases/nnbd/issue41700b.dart:11:5: Error: The method 'foo' isn't defined for the class 'Null?'.
+ - 'Null' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+ y.foo();
+ ^^^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41700b.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41700b.dart.weak.transformed.expect
new file mode 100644
index 0000000..79e8633
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue41700b.dart.weak.transformed.expect
@@ -0,0 +1,49 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue41700b.dart:8:12: Error: A value of type 'Null/*1*/' can't be assigned to a variable of type 'Null/*2*/'.
+// - 'Null/*1*/' is from 'dart:core'.
+// - 'Null/*2*/' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+// Null x = null;
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue41700b.dart:9:5: Error: The method 'foo' isn't defined for the class 'Null'.
+// - 'Null' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+// Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+// x.foo();
+// ^^^
+//
+// pkg/front_end/testcases/nnbd/issue41700b.dart:11:5: Error: The method 'foo' isn't defined for the class 'Null?'.
+// - 'Null' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+// Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+// y.foo();
+// ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Null extends core::Object {
+ synthetic constructor •() → self::Null
+ : super core::Object::•()
+ ;
+}
+static method test() → dynamic {
+ self::Null x = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41700b.dart:8:12: Error: A value of type 'Null/*1*/' can't be assigned to a variable of type 'Null/*2*/'.
+ - 'Null/*1*/' is from 'dart:core'.
+ - 'Null/*2*/' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+ Null x = null;
+ ^" in null as{TypeError,ForNonNullableByDefault} self::Null;
+ invalid-expression "pkg/front_end/testcases/nnbd/issue41700b.dart:9:5: Error: The method 'foo' isn't defined for the class 'Null'.
+ - 'Null' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+ x.foo();
+ ^^^";
+ self::Null? y = null;
+ invalid-expression "pkg/front_end/testcases/nnbd/issue41700b.dart:11:5: Error: The method 'foo' isn't defined for the class 'Null?'.
+ - 'Null' is from 'pkg/front_end/testcases/nnbd/issue41700b.dart'.
+Try correcting the name to the name of an existing method, or defining a method named 'foo'.
+ y.foo();
+ ^^^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue_39286.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue_39286.dart.textual_outline.expect
new file mode 100644
index 0000000..c90f902
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue_39286.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class C {
+ D? f() => new D();
+ void h() {}
+}
+
+class D {
+ void g() {}
+}
+
+void test(C x) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue_39286.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue_39286.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c43f630
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue_39286.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+class C {
+ D? f() => new D();
+ void h() {}
+}
+
+class D {
+ void g() {}
+}
+
+main() {}
+void test(C x) {}
diff --git a/pkg/front_end/testcases/nnbd/issue_39286_2.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue_39286_2.dart.textual_outline.expect
new file mode 100644
index 0000000..15af755
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue_39286_2.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+class C {
+ int y = 42;
+ D? f() => new D();
+ C h() => this;
+}
+
+class D {
+ D g() => this;
+ String operator [](String s) {}
+}
+
+void test(C x) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue_39286_2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue_39286_2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bf01dba
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue_39286_2.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+class C {
+ C h() => this;
+ D? f() => new D();
+ int y = 42;
+}
+
+class D {
+ D g() => this;
+ String operator [](String s) {}
+}
+
+main() {}
+void test(C x) {}
diff --git a/pkg/front_end/testcases/nnbd/late.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/late.dart.textual_outline.expect
new file mode 100644
index 0000000..596c5f8
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/late.dart.textual_outline.expect
@@ -0,0 +1,33 @@
+late int ;
+lateTopLevelField;
+late ;
+final int lateFinalTopLevelField;
+late ;
+final int lateFinalTopLevelFieldWithInit = 0;
+class Class {
+ late int ;
+ lateInstanceField;
+ late ;
+ final int lateFinalInstanceField1;
+ late ;
+ final int lateFinalInstanceField2;
+ late ;
+ final int lateFinalInstanceFieldWithInit = 0;
+ late Class ;
+ lateInstanceFieldThis = this;
+ late ;
+ final Class lateFinalInstanceFieldThis = this;
+ static late int ;
+ lateStaticField;
+ static late ;
+ final int lateFinalStaticField1;
+ static late ;
+ final int lateFinalStaticField2;
+ static late ;
+ final int lateFinalStaticFieldWithInit = 0;
+ method() { }
+ methodWithErrors() { }
+}
+main() { }
+noErrors() { }
+errors() { }
diff --git a/pkg/front_end/testcases/nnbd/later.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/later.dart.textual_outline.expect
new file mode 100644
index 0000000..e0c821d
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/later.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+class A {
+ int a = 42;
+ late int ;
+ b = (this.a * 2) >> 1;
+ foo(late int x) { }
+}
+bar(late int x) { }
+baz() { }
+hest() async { }
+fisk() async { }
+class B {
+ late ;
+ final int x = 42;
+ const B();
+}
+class C {
+ late ;
+ final int x;
+ initVars() { }
+}
+main() { }
diff --git a/pkg/front_end/testcases/nnbd/lhs_of_if_null.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/lhs_of_if_null.dart.textual_outline.expect
new file mode 100644
index 0000000..145fce3
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/lhs_of_if_null.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+Object f() => g(null) ?? 0;
+T g<T>(T t) => t;
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/lhs_of_if_null.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/lhs_of_if_null.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..145fce3
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/lhs_of_if_null.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+Object f() => g(null) ?? 0;
+T g<T>(T t) => t;
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/list_constructor.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/list_constructor.dart.textual_outline.expect
new file mode 100644
index 0000000..81dcd51
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/list_constructor.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+foo<T extends Object?>() {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/list_constructor.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/list_constructor.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..81dcd51
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/list_constructor.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+foo<T extends Object?>() {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/literal_from_opt_in.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/literal_from_opt_in.dart.textual_outline.expect
new file mode 100644
index 0000000..cd7a827
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/literal_from_opt_in.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+// @dart = 2.5
+import 'literal_from_opt_in_lib.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/literal_from_opt_in.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/literal_from_opt_in.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cd7a827
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/literal_from_opt_in.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+// @dart = 2.5
+import 'literal_from_opt_in_lib.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/load_library.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/load_library.dart.textual_outline.expect
new file mode 100644
index 0000000..8f208e0
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/load_library.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+import "dart:math" deferred as math;
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/load_library.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/load_library.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8f208e0
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/load_library.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+import "dart:math" deferred as math;
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_in.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_in.dart.textual_outline.expect
new file mode 100644
index 0000000..af85f0d
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_in.dart.textual_outline.expect
@@ -0,0 +1,28 @@
+// @dart = 2.5
+import 'member_inheritance_from_opt_in_lib.dart';
+
+class LegacyClass extends Class implements Interface {
+ int method3() => 0;
+ int method4() => 0;
+ int method6a(int a, int b) => 0;
+ int method6b(int a, [int b]) => 0;
+ int method6c([int a, int b]) => 0;
+ int method8a(int a, {int b: 0}) => 0;
+ int method8b({int a, int b: 0}) => 0;
+ int method10a(int a, {int b}) => 0;
+ int method10b({int a, int b}) => 0;
+ int get getter3 => 0;
+ int get getter4 => 0;
+ void set setter3(int value) {}
+ void set setter4(int value) {}
+ int field3;
+ int field4;
+ int get property3 => 0;
+ void set property3(int value) {}
+ int get property4 => 0;
+ void set property4(int value) {}
+ int property7;
+ int property8;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_in.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_in.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0cad16e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_in.dart.textual_outline_modelled.expect
@@ -0,0 +1,28 @@
+// @dart = 2.5
+import 'member_inheritance_from_opt_in_lib.dart';
+
+class LegacyClass extends Class implements Interface {
+ int field3;
+ int field4;
+ int get getter3 => 0;
+ int get getter4 => 0;
+ int get property3 => 0;
+ int get property4 => 0;
+ int method10a(int a, {int b}) => 0;
+ int method10b({int a, int b}) => 0;
+ int method3() => 0;
+ int method4() => 0;
+ int method6a(int a, int b) => 0;
+ int method6b(int a, [int b]) => 0;
+ int method6c([int a, int b]) => 0;
+ int method8a(int a, {int b: 0}) => 0;
+ int method8b({int a, int b: 0}) => 0;
+ int property7;
+ int property8;
+ void set property3(int value) {}
+ void set property4(int value) {}
+ void set setter3(int value) {}
+ void set setter4(int value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_out.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_out.dart.textual_outline.expect
new file mode 100644
index 0000000..b7107c1
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_out.dart.textual_outline.expect
@@ -0,0 +1,81 @@
+library main;
+
+import 'member_inheritance_from_opt_out_lib.dart';
+
+abstract class Interface {
+ int method1();
+ int? method2();
+ int method3a(int a, int b);
+ int method3b(int a, [int b]);
+ int method3c([int a, int b]);
+ int? method4a(int? a, int? b);
+ int? method4b(int? a, [int? b]);
+ int? method4c([int? a, int? b]);
+ int method5a(int a, {int b: 0});
+ int method5b({int a: 0, int b: 0});
+ int method5c({required int a, required int b});
+ int? method6a(int? a, {int? b});
+ int? method6b({int? a, int? b});
+ int? method6c({required int? a, required int? b});
+ int get getter1;
+ int? get getter2;
+ void set setter1(int value);
+ void set setter2(int? value);
+ int field1 = 0;
+ int? field2;
+ int get field3;
+ void set field3(int value);
+ int? get field4;
+ void set field4(int? value);
+ int get property1;
+ void set property1(int value);
+ int? get property2;
+ void set property2(int? value);
+ int property3 = 0;
+ int? property4;
+}
+
+class Class1 extends LegacyClass {}
+
+class Class2a extends LegacyClass implements Interface {}
+
+class Class2b extends LegacyClass implements Interface {
+ int method1() => 0;
+ int? method2() => 0;
+ int method3a(int a, int b) => 0;
+ int method3b(int a, [int b = 42]) => 0;
+ int method3c([int a = 42, int b = 42]) => 0;
+ int? method4a(int? a, int? b) => 0;
+ int? method4b(int? a, [int? b]) => 0;
+ int? method4c([int? a, int? b]) => 0;
+ int method5a(int a, {int b: 0}) => 0;
+ int method5b({int a: 0, int b: 0}) => 0;
+ int method5c({required int a, required int b}) => 0;
+ int? method6a(int? a, {int? b}) => 0;
+ int? method6b({int? a, int? b}) => 0;
+ int? method6c({required int? a, required int? b}) => 0;
+ int get getter1 => 0;
+ int? get getter2 => 0;
+ void set setter1(int value) {}
+ void set setter2(int? value) {}
+ int field1 = 0;
+ int? field2;
+ int get field3 => 0;
+ void set field3(int value) {}
+ int? get field4 => 0;
+ void set field4(int? value) {}
+ int get property1 => 0;
+ void set property1(int value) {}
+ int? get property2 => 0;
+ void set property2(int? value) {}
+ int property3 = 0;
+ int? property4;
+}
+
+class Class3a extends GenericLegacyClass<int> {}
+
+class Class3b extends GenericLegacyClass<int?> {}
+
+class Class3c<S> extends GenericLegacyClass<S> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_out.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_out.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..860366f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_out.dart.textual_outline_modelled.expect
@@ -0,0 +1,81 @@
+library main;
+
+import 'member_inheritance_from_opt_out_lib.dart';
+
+abstract class Interface {
+ int field1 = 0;
+ int get field3;
+ int get getter1;
+ int get property1;
+ int method1();
+ int method3a(int a, int b);
+ int method3b(int a, [int b]);
+ int method3c([int a, int b]);
+ int method5a(int a, {int b: 0});
+ int method5b({int a: 0, int b: 0});
+ int method5c({required int a, required int b});
+ int property3 = 0;
+ int? field2;
+ int? get field4;
+ int? get getter2;
+ int? get property2;
+ int? method2();
+ int? method4a(int? a, int? b);
+ int? method4b(int? a, [int? b]);
+ int? method4c([int? a, int? b]);
+ int? method6a(int? a, {int? b});
+ int? method6b({int? a, int? b});
+ int? method6c({required int? a, required int? b});
+ int? property4;
+ void set field3(int value);
+ void set field4(int? value);
+ void set property1(int value);
+ void set property2(int? value);
+ void set setter1(int value);
+ void set setter2(int? value);
+}
+
+class Class1 extends LegacyClass {}
+
+class Class2a extends LegacyClass implements Interface {}
+
+class Class2b extends LegacyClass implements Interface {
+ int field1 = 0;
+ int get field3 => 0;
+ int get getter1 => 0;
+ int get property1 => 0;
+ int method1() => 0;
+ int method3a(int a, int b) => 0;
+ int method3b(int a, [int b = 42]) => 0;
+ int method3c([int a = 42, int b = 42]) => 0;
+ int method5a(int a, {int b: 0}) => 0;
+ int method5b({int a: 0, int b: 0}) => 0;
+ int method5c({required int a, required int b}) => 0;
+ int property3 = 0;
+ int? field2;
+ int? get field4 => 0;
+ int? get getter2 => 0;
+ int? get property2 => 0;
+ int? method2() => 0;
+ int? method4a(int? a, int? b) => 0;
+ int? method4b(int? a, [int? b]) => 0;
+ int? method4c([int? a, int? b]) => 0;
+ int? method6a(int? a, {int? b}) => 0;
+ int? method6b({int? a, int? b}) => 0;
+ int? method6c({required int? a, required int? b}) => 0;
+ int? property4;
+ void set field3(int value) {}
+ void set field4(int? value) {}
+ void set property1(int value) {}
+ void set property2(int? value) {}
+ void set setter1(int value) {}
+ void set setter2(int? value) {}
+}
+
+class Class3a extends GenericLegacyClass<int> {}
+
+class Class3b extends GenericLegacyClass<int?> {}
+
+class Class3c<S> extends GenericLegacyClass<S> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart.textual_outline.expect
new file mode 100644
index 0000000..ac9dab0
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart.textual_outline.expect
@@ -0,0 +1,26 @@
+import 'messages_with_types_opt_out.dart';
+
+class SuperIn {
+ String? nullableSame() => "foo";
+ String nonNullableSame() => "bar";
+ int? nullableBad<T>(T t) => 1;
+ int nonNullableBad<T>(T t) => 2;
+}
+
+class SubInIn extends SuperIn {
+ String? nullableSame() => "foo";
+ String nonNullableSame() => "bar";
+ T? nullableBad<T>(T t) => null;
+ T nonNullableBad<T>(T t) => t;
+}
+
+class SubOutIn extends SuperOut {
+ String? nullableSame() => "foo";
+ String nonNullableSame() => "bar";
+ T? nullableBad<T>(T t) => null;
+ T nonNullableBad<T>(T t) => t;
+}
+
+int Function()? nullableVar = () => 3;
+double nonNullableVar = 4.0;
+testOptIn() {}
diff --git a/pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0f30fad
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart.textual_outline_modelled.expect
@@ -0,0 +1,26 @@
+import 'messages_with_types_opt_out.dart';
+
+class SubInIn extends SuperIn {
+ String nonNullableSame() => "bar";
+ String? nullableSame() => "foo";
+ T nonNullableBad<T>(T t) => t;
+ T? nullableBad<T>(T t) => null;
+}
+
+class SubOutIn extends SuperOut {
+ String nonNullableSame() => "bar";
+ String? nullableSame() => "foo";
+ T nonNullableBad<T>(T t) => t;
+ T? nullableBad<T>(T t) => null;
+}
+
+class SuperIn {
+ String nonNullableSame() => "bar";
+ String? nullableSame() => "foo";
+ int nonNullableBad<T>(T t) => 2;
+ int? nullableBad<T>(T t) => 1;
+}
+
+double nonNullableVar = 4.0;
+int Function()? nullableVar = () => 3;
+testOptIn() {}
diff --git a/pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart.textual_outline.expect
new file mode 100644
index 0000000..3271b71
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart.textual_outline.expect
@@ -0,0 +1,26 @@
+// @dart = 2.5
+import 'messages_with_types_opt_in.dart';
+
+class SuperOut {
+ String nullableSame() => "foo";
+ String nonNullableSame() => "bar";
+ int nullableBad<T>(T t) => 1;
+ int nonNullableBad<T>(T t) => 2;
+}
+
+class SubOutOut extends SuperOut {
+ String nullableSame() => "foo";
+ String nonNullableSame() => "bar";
+ T nullableBad<T>(T t) => null;
+ T nonNullableBad<T>(T t) => t;
+}
+
+class SubInOut extends SuperIn {
+ String nullableSame() => "foo";
+ String nonNullableSame() => "bar";
+ T nullableBad<T>(T t) => null;
+ T nonNullableBad<T>(T t) => t;
+}
+
+String legacyVar = "legacy";
+testOptOut() {}
diff --git a/pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..29aa4bf
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart.textual_outline_modelled.expect
@@ -0,0 +1,27 @@
+// @dart = 2.5
+import 'messages_with_types_opt_in.dart';
+
+String legacyVar = "legacy";
+
+class SubInOut extends SuperIn {
+ String nonNullableSame() => "bar";
+ String nullableSame() => "foo";
+ T nonNullableBad<T>(T t) => t;
+ T nullableBad<T>(T t) => null;
+}
+
+class SubOutOut extends SuperOut {
+ String nonNullableSame() => "bar";
+ String nullableSame() => "foo";
+ T nonNullableBad<T>(T t) => t;
+ T nullableBad<T>(T t) => null;
+}
+
+class SuperOut {
+ String nonNullableSame() => "bar";
+ String nullableSame() => "foo";
+ int nonNullableBad<T>(T t) => 2;
+ int nullableBad<T>(T t) => 1;
+}
+
+testOptOut() {}
diff --git a/pkg/front_end/testcases/nnbd/missing_required_named_parameter.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/missing_required_named_parameter.dart.textual_outline.expect
new file mode 100644
index 0000000..1e4f84b
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/missing_required_named_parameter.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+void foo({required String s}) {}
+void Function({required String s}) g = ({required String s}) {};
+
+class A {
+ A({required int x});
+ foo({required int y}) {}
+ void Function({required String s}) f = ({required String s}) {};
+}
+
+bar() {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/missing_required_named_parameter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/missing_required_named_parameter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d6834e7
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/missing_required_named_parameter.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+bar() {}
+
+class A {
+ A({required int x});
+ foo({required int y}) {}
+ void Function({required String s}) f = ({required String s}) {};
+}
+
+main() {}
+void Function({required String s}) g = ({required String s}) {};
+void foo({required String s}) {}
diff --git a/pkg/front_end/testcases/nnbd/mixed_mode_hierarchy_generic_methods.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/mixed_mode_hierarchy_generic_methods.dart.textual_outline.expect
new file mode 100644
index 0000000..2200093
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/mixed_mode_hierarchy_generic_methods.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+import './mixed_mode_hierarchy_generic_methods_lib.dart';
+import "dart:async";
+
+class B implements A<int> {
+ then<B>() => Future<B>.value();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/mixed_mode_hierarchy_generic_methods.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/mixed_mode_hierarchy_generic_methods.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2200093
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/mixed_mode_hierarchy_generic_methods.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+import './mixed_mode_hierarchy_generic_methods_lib.dart';
+import "dart:async";
+
+class B implements A<int> {
+ then<B>() => Future<B>.value();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/mixin_from_opt_in.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/mixin_from_opt_in.dart.textual_outline.expect
new file mode 100644
index 0000000..fbc1a75
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/mixin_from_opt_in.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'mixin_from_opt_in_lib.dart';
+
+class Class extends Object with Mixin {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/mixin_from_opt_in.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/mixin_from_opt_in.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fbc1a75
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/mixin_from_opt_in.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.6
+import 'mixin_from_opt_in_lib.dart';
+
+class Class extends Object with Mixin {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/mixin_from_opt_in_out_in.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/mixin_from_opt_in_out_in.dart.textual_outline.expect
new file mode 100644
index 0000000..3a5ba05
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/mixin_from_opt_in_out_in.dart.textual_outline.expect
@@ -0,0 +1,20 @@
+import 'mixin_from_opt_in_out_in_lib1.dart';
+import 'mixin_from_opt_in_out_in_lib2.dart';
+
+class DiB0 extends C0 implements B {}
+
+class DiBq0 extends C0 implements Bq {}
+
+class DwB0 extends C0 with B {}
+
+class DwBq0 extends C0 with Bq {}
+
+class DiB3 extends C3 implements B {}
+
+class DiBq3 extends C3 implements Bq {}
+
+class DwB3 extends C3 with B {}
+
+class DwBq3 extends C3 with Bq {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/mixin_from_opt_in_out_in.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/mixin_from_opt_in_out_in.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b095d49
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/mixin_from_opt_in_out_in.dart.textual_outline_modelled.expect
@@ -0,0 +1,20 @@
+import 'mixin_from_opt_in_out_in_lib1.dart';
+import 'mixin_from_opt_in_out_in_lib2.dart';
+
+class DiB0 extends C0 implements B {}
+
+class DiB3 extends C3 implements B {}
+
+class DiBq0 extends C0 implements Bq {}
+
+class DiBq3 extends C3 implements Bq {}
+
+class DwB0 extends C0 with B {}
+
+class DwB3 extends C3 with B {}
+
+class DwBq0 extends C0 with Bq {}
+
+class DwBq3 extends C3 with Bq {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/mixin_from_opt_out.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/mixin_from_opt_out.dart.textual_outline.expect
new file mode 100644
index 0000000..07b9747
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/mixin_from_opt_out.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'mixin_from_opt_out_lib.dart';
+
+class Class extends Object with Mixin {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/mixin_from_opt_out.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/mixin_from_opt_out.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..07b9747
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/mixin_from_opt_out.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import 'mixin_from_opt_out_lib.dart';
+
+class Class extends Object with Mixin {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/never_bound.dart.strong.expect b/pkg/front_end/testcases/nnbd/never_bound.dart.strong.expect
index de5b31d..8d4563e 100644
--- a/pkg/front_end/testcases/nnbd/never_bound.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/never_bound.dart.strong.expect
@@ -2,7 +2,7 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/nnbd/never_bound.dart:10:3: Error: Type argument 'Null?' doesn't conform to the bound 'Never' of the type variable 'T' on 'GenericNever'.
+// pkg/front_end/testcases/nnbd/never_bound.dart:10:3: Error: Type argument 'Null' doesn't conform to the bound 'Never' of the type variable 'T' on 'GenericNever'.
// Try changing type arguments so that they conform to the bounds.
// GenericNever<Null>();
// ^
diff --git a/pkg/front_end/testcases/nnbd/never_bound.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/never_bound.dart.strong.transformed.expect
index de5b31d..8d4563e 100644
--- a/pkg/front_end/testcases/nnbd/never_bound.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/never_bound.dart.strong.transformed.expect
@@ -2,7 +2,7 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/nnbd/never_bound.dart:10:3: Error: Type argument 'Null?' doesn't conform to the bound 'Never' of the type variable 'T' on 'GenericNever'.
+// pkg/front_end/testcases/nnbd/never_bound.dart:10:3: Error: Type argument 'Null' doesn't conform to the bound 'Never' of the type variable 'T' on 'GenericNever'.
// Try changing type arguments so that they conform to the bounds.
// GenericNever<Null>();
// ^
diff --git a/pkg/front_end/testcases/nnbd/never_bound.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/never_bound.dart.textual_outline.expect
new file mode 100644
index 0000000..9004607
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/never_bound.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class GenericNever<T extends Never> {
+ dynamic getParamType() => T;
+}
+
+errors() {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/never_bound.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/never_bound.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9004607
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/never_bound.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class GenericNever<T extends Never> {
+ dynamic getParamType() => T;
+}
+
+errors() {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/never_bound.dart.weak.expect b/pkg/front_end/testcases/nnbd/never_bound.dart.weak.expect
index de5b31d..8d4563e 100644
--- a/pkg/front_end/testcases/nnbd/never_bound.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/never_bound.dart.weak.expect
@@ -2,7 +2,7 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/nnbd/never_bound.dart:10:3: Error: Type argument 'Null?' doesn't conform to the bound 'Never' of the type variable 'T' on 'GenericNever'.
+// pkg/front_end/testcases/nnbd/never_bound.dart:10:3: Error: Type argument 'Null' doesn't conform to the bound 'Never' of the type variable 'T' on 'GenericNever'.
// Try changing type arguments so that they conform to the bounds.
// GenericNever<Null>();
// ^
diff --git a/pkg/front_end/testcases/nnbd/never_bound.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/never_bound.dart.weak.transformed.expect
index de5b31d..8d4563e 100644
--- a/pkg/front_end/testcases/nnbd/never_bound.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/never_bound.dart.weak.transformed.expect
@@ -2,7 +2,7 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/nnbd/never_bound.dart:10:3: Error: Type argument 'Null?' doesn't conform to the bound 'Never' of the type variable 'T' on 'GenericNever'.
+// pkg/front_end/testcases/nnbd/never_bound.dart:10:3: Error: Type argument 'Null' doesn't conform to the bound 'Never' of the type variable 'T' on 'GenericNever'.
// Try changing type arguments so that they conform to the bounds.
// GenericNever<Null>();
// ^
diff --git a/pkg/front_end/testcases/nnbd/never_opt_out.dart.strong.expect b/pkg/front_end/testcases/nnbd/never_opt_out.dart.strong.expect
index 83a210a..b3d52ba 100644
--- a/pkg/front_end/testcases/nnbd/never_opt_out.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/never_opt_out.dart.strong.expect
@@ -102,7 +102,7 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/nnbd/never_opt_out_lib.dart:19:28: Error: A value of type 'Type' can't be assigned to a variable of type 'Null?'.
+// pkg/front_end/testcases/nnbd/never_opt_out_lib.dart:19:28: Error: A value of type 'Type' can't be assigned to a variable of type 'Null'.
// - 'Type' is from 'dart:core'.
// Null get nullProperty => Null;
// ^
@@ -127,7 +127,7 @@
method nullMethod(core::Null? value) → core::Null?
return value;
get nullProperty() → core::Null?
- return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/never_opt_out_lib.dart:19:28: Error: A value of type 'Type' can't be assigned to a variable of type 'Null?'.
+ return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/never_opt_out_lib.dart:19:28: Error: A value of type 'Type' can't be assigned to a variable of type 'Null'.
- 'Type' is from 'dart:core'.
Null get nullProperty => Null;
^" in core::Null? as{TypeError,ForNonNullableByDefault} core::Null?;
diff --git a/pkg/front_end/testcases/nnbd/never_opt_out.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/never_opt_out.dart.textual_outline.expect
new file mode 100644
index 0000000..0630e92
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/never_opt_out.dart.textual_outline.expect
@@ -0,0 +1,30 @@
+// @dart = 2.6
+import 'never_opt_out_lib.dart';
+
+Never optOutNever;
+var inferredOptOutNever = optInNever;
+main() {}
+
+class B extends A {
+ Null neverField;
+ Null neverMethod(Null value) => value;
+ Null get neverProperty => null;
+ void set neverProperty(Null value) {}
+ Null nullField;
+ Null nullMethod(Null value) => value;
+ Null get nullProperty => null;
+ void set nullProperty(Null value) {}
+}
+
+class C extends A {
+ Never neverField;
+ Never neverMethod(Never value) => value;
+ Never get neverProperty => null;
+ void set neverProperty(Never value) {}
+ Never nullField;
+ Never nullMethod(Never value) => value;
+ Never get nullProperty => null;
+ void set nullProperty(Never value) {}
+}
+
+throws(void Function() f) {}
diff --git a/pkg/front_end/testcases/nnbd/never_opt_out.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/never_opt_out.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..26f5017
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/never_opt_out.dart.textual_outline_modelled.expect
@@ -0,0 +1,30 @@
+// @dart = 2.6
+import 'never_opt_out_lib.dart';
+
+Never optOutNever;
+
+class B extends A {
+ Null get neverProperty => null;
+ Null get nullProperty => null;
+ Null neverField;
+ Null neverMethod(Null value) => value;
+ Null nullField;
+ Null nullMethod(Null value) => value;
+ void set neverProperty(Null value) {}
+ void set nullProperty(Null value) {}
+}
+
+class C extends A {
+ Never get neverProperty => null;
+ Never get nullProperty => null;
+ Never neverField;
+ Never neverMethod(Never value) => value;
+ Never nullField;
+ Never nullMethod(Never value) => value;
+ void set neverProperty(Never value) {}
+ void set nullProperty(Never value) {}
+}
+
+main() {}
+throws(void Function() f) {}
+var inferredOptOutNever = optInNever;
diff --git a/pkg/front_end/testcases/nnbd/never_opt_out.dart.weak.expect b/pkg/front_end/testcases/nnbd/never_opt_out.dart.weak.expect
index 83a210a..b3d52ba 100644
--- a/pkg/front_end/testcases/nnbd/never_opt_out.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/never_opt_out.dart.weak.expect
@@ -102,7 +102,7 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/nnbd/never_opt_out_lib.dart:19:28: Error: A value of type 'Type' can't be assigned to a variable of type 'Null?'.
+// pkg/front_end/testcases/nnbd/never_opt_out_lib.dart:19:28: Error: A value of type 'Type' can't be assigned to a variable of type 'Null'.
// - 'Type' is from 'dart:core'.
// Null get nullProperty => Null;
// ^
@@ -127,7 +127,7 @@
method nullMethod(core::Null? value) → core::Null?
return value;
get nullProperty() → core::Null?
- return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/never_opt_out_lib.dart:19:28: Error: A value of type 'Type' can't be assigned to a variable of type 'Null?'.
+ return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/never_opt_out_lib.dart:19:28: Error: A value of type 'Type' can't be assigned to a variable of type 'Null'.
- 'Type' is from 'dart:core'.
Null get nullProperty => Null;
^" in core::Null? as{TypeError,ForNonNullableByDefault} core::Null?;
diff --git a/pkg/front_end/testcases/nnbd/never_receiver.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/never_receiver.dart.textual_outline.expect
new file mode 100644
index 0000000..741b909
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/never_receiver.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+foo(Never x, Never? y) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/never_receiver.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/never_receiver.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..741b909
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/never_receiver.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+foo(Never x, Never? y) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/nnbd_opt_out_language_version.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/nnbd_opt_out_language_version.dart.textual_outline.expect
new file mode 100644
index 0000000..339b98f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nnbd_opt_out_language_version.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+// @dart = 2.4
+class late {
+ int get g => 1;
+}
+
+class required {
+ int get g => 2;
+}
+
+class C {
+ late l = late();
+ required r = required();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/nnbd_opt_out_language_version.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/nnbd_opt_out_language_version.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2ef980b
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nnbd_opt_out_language_version.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+// @dart = 2.4
+class C {
+ late l = late();
+ required r = required();
+}
+
+class late {
+ int get g => 1;
+}
+
+class required {
+ int get g => 2;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/nnbd_opt_out_language_version_try_to_trick.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/nnbd_opt_out_language_version_try_to_trick.dart.textual_outline.expect
new file mode 100644
index 0000000..890940b
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nnbd_opt_out_language_version_try_to_trick.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+// @dart = 2.4
+// @dart = 2.8
+class late {
+ int get g => 1;
+}
+
+class required {
+ int get g => 2;
+}
+
+class C {
+ late l = late();
+ required r = required();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/nnbd_opt_out_language_version_try_to_trick.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/nnbd_opt_out_language_version_try_to_trick.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9ad8c9f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nnbd_opt_out_language_version_try_to_trick.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+// @dart = 2.4
+// @dart = 2.8
+class C {
+ late l = late();
+ required r = required();
+}
+
+class late {
+ int get g => 1;
+}
+
+class required {
+ int get g => 2;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/no_null_shorting.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/no_null_shorting.dart.textual_outline.expect
new file mode 100644
index 0000000..6a4cb41
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/no_null_shorting.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+// @dart = 2.6
+class Class {
+ Class field;
+ Class method() => field;
+ Class operator [](Class key) => field;
+ void operator []=(Class key, Class value) {}
+ Class operator +(int value) => field;
+ Class operator -() => field;
+}
+
+main() {}
+void propertyAccess(Class c) {}
+void indexAccess(Class c) {}
+void operatorAccess(Class c) {}
+void ifNull(Class c) {}
+void throws(void Function() f) {}
diff --git a/pkg/front_end/testcases/nnbd/no_null_shorting.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/no_null_shorting.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1e31843
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/no_null_shorting.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+// @dart = 2.6
+class Class {
+ Class field;
+ Class method() => field;
+ Class operator +(int value) => field;
+ Class operator -() => field;
+ Class operator [](Class key) => field;
+ void operator []=(Class key, Class value) {}
+}
+
+main() {}
+void ifNull(Class c) {}
+void indexAccess(Class c) {}
+void operatorAccess(Class c) {}
+void propertyAccess(Class c) {}
+void throws(void Function() f) {}
diff --git a/pkg/front_end/testcases/nnbd/no_null_shorting_explicit_extension.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/no_null_shorting_explicit_extension.dart.textual_outline.expect
new file mode 100644
index 0000000..7fdf2c8
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/no_null_shorting_explicit_extension.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+// @dart = 2.6
+class Class {
+ Class _field;
+}
+extension Extension ;
+on Class (){ }
+main() { }
+void propertyAccess(Class c) { }
+void indexAccess(Class c) { }
+void operatorAccess(Class c) { }
+void ifNull(Class c) { }
+void throws(void Function() f) { }
diff --git a/pkg/front_end/testcases/nnbd/no_null_shorting_extension.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/no_null_shorting_extension.dart.textual_outline.expect
new file mode 100644
index 0000000..7fdf2c8
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/no_null_shorting_extension.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+// @dart = 2.6
+class Class {
+ Class _field;
+}
+extension Extension ;
+on Class (){ }
+main() { }
+void propertyAccess(Class c) { }
+void indexAccess(Class c) { }
+void operatorAccess(Class c) { }
+void ifNull(Class c) { }
+void throws(void Function() f) { }
diff --git a/pkg/front_end/testcases/nnbd/non_nullable_field_initialization.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/non_nullable_field_initialization.dart.textual_outline.expect
new file mode 100644
index 0000000..bceca95
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/non_nullable_field_initialization.dart.textual_outline.expect
@@ -0,0 +1,71 @@
+class Foo {
+}
+int topLevelField;
+class A {
+ static int staticFieldOfA;
+ int fieldOfA;
+ A.foo();
+ A.bar(this.fieldOfA);
+}
+class B<X extends Object?, Y extends Object> {
+ X fieldOfB;
+ Y fieldOfB2;
+ B.foo();
+ B.bar(this.fieldOfB, this.fieldOfB2);
+}
+mixin M {
+ static int staticFieldOfM;
+ int fieldOfM;
+}
+mixin N<X extends Object?, Y extends Object> {
+ X fieldOfN;
+ Y fieldOfN2;
+}
+extension P ;
+on Foo (){ }
+int? nullableTopLevelField;
+late int ;
+lateTopLevelField;
+int topLevelFieldWithInitializer = 42;
+class C<X extends Object?, Y extends Object> {
+ static int? staticFieldOfX;
+ static int staticFieldOfXInitialized = 42;
+ X? fieldOfX;
+ int? fieldOfX2;
+ dynamic fieldOfX3;
+ Null fieldOfX4;
+ int Function()? fieldOfX5;
+ Y? fieldOfX6;
+ static late int ;
+ lateStaticFieldOfC;
+ late int ;
+ fieldOfC7;
+ late X ;
+ fieldOfC8;
+ late Y ;
+ fieldOfC9;
+ int fieldOfC10;
+ C.foo(this.fieldOfC10);
+ C.bar(this.fieldOfC10);
+}
+mixin L<X extends Object?, Y extends Object> {
+ static int? staticFieldOfL;
+ static int staticFieldOfLInitialized = 42;
+ X? fieldOfL;
+ int? fieldOfL2;
+ dynamic fieldOfL3;
+ Null fieldOfL4;
+ int Function()? fieldOfL5;
+ Y? fieldOfL6;
+ static late int ;
+ lateStaticFieldOfM;
+ late int ;
+ fieldOfM7;
+ late X ;
+ fieldOfM8;
+ late Y ;
+ fieldOfM9;
+}
+extension Q ;
+on Foo (){ }
+main() { }
diff --git a/pkg/front_end/testcases/nnbd/non_nullable_optional.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/non_nullable_optional.dart.textual_outline.expect
new file mode 100644
index 0000000..14da563
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/non_nullable_optional.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+part 'non_nullable_optional_part.dart';
+
+main() {}
+method1({int a}) {}
+method2([int a]) {}
diff --git a/pkg/front_end/testcases/nnbd/non_nullable_optional.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/non_nullable_optional.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..14da563
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/non_nullable_optional.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+part 'non_nullable_optional_part.dart';
+
+main() {}
+method1({int a}) {}
+method2([int a]) {}
diff --git a/pkg/front_end/testcases/nnbd/not_definitely_unassigned_late_local_variables.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/not_definitely_unassigned_late_local_variables.dart.textual_outline.expect
new file mode 100644
index 0000000..b52ce01
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/not_definitely_unassigned_late_local_variables.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+abstract class A<T> {
+ T baz();
+ bar(T value) {}
+ barInt(int value) {}
+ foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/not_definitely_unassigned_late_local_variables.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/not_definitely_unassigned_late_local_variables.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b52ce01
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/not_definitely_unassigned_late_local_variables.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+abstract class A<T> {
+ T baz();
+ bar(T value) {}
+ barInt(int value) {}
+ foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.textual_outline.expect
new file mode 100644
index 0000000..2c1d4b5
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+// @dart = 2.6
+import 'nsm_from_opt_in_lib.dart';
+
+abstract class A2 implements A {
+ @override
+ noSuchMethod(Invocation invocation) {}
+}
+
+abstract class B2 extends A implements C2 {
+ @override
+ noSuchMethod(Invocation invocation) {}
+}
+
+abstract class C2 {
+ int method(int i, {optional});
+ T genericMethod1<T>(T t);
+ T genericMethod2<T extends Object>(T t);
+ T genericMethod3<T extends Object>(T t);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b08f82b
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nsm_from_opt_in.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+// @dart = 2.6
+import 'nsm_from_opt_in_lib.dart';
+
+abstract class A2 implements A {
+ @override
+ noSuchMethod(Invocation invocation) {}
+}
+
+abstract class B2 extends A implements C2 {
+ @override
+ noSuchMethod(Invocation invocation) {}
+}
+
+abstract class C2 {
+ T genericMethod1<T>(T t);
+ T genericMethod2<T extends Object>(T t);
+ T genericMethod3<T extends Object>(T t);
+ int method(int i, {optional});
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/null_access.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/null_access.dart.textual_outline.expect
new file mode 100644
index 0000000..69042fc
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/null_access.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+class Class {
+ int nonNullableField = 0;
+ int? nullableField;
+ int operator [](int key) => key;
+ void operator []=(int key, int value) {}
+ Class get nonNullableClass => this;
+ Class call() => this;
+ NullableIndexClass get nonNullableNullableIndexClass => NullableIndexClass();
+}
+
+class NullableIndexClass {
+ int? operator [](int key) => key;
+ void operator []=(int key, int value) {}
+}
+
+main() {}
+errors(Class? nullableClass, Class nonNullableClass, int? nullableInt,
+ int nonNullableInt, NullableIndexClass? nullableNullableIndexClass) {}
diff --git a/pkg/front_end/testcases/nnbd/null_access.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/null_access.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..849bf32
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/null_access.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+class Class {
+ Class call() => this;
+ Class get nonNullableClass => this;
+ NullableIndexClass get nonNullableNullableIndexClass => NullableIndexClass();
+ int nonNullableField = 0;
+ int operator [](int key) => key;
+ int? nullableField;
+ void operator []=(int key, int value) {}
+}
+
+class NullableIndexClass {
+ int? operator [](int key) => key;
+ void operator []=(int key, int value) {}
+}
+
+errors(Class? nullableClass, Class nonNullableClass, int? nullableInt,
+ int nonNullableInt, NullableIndexClass? nullableNullableIndexClass) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/null_aware_chain.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/null_aware_chain.dart.textual_outline.expect
new file mode 100644
index 0000000..2215727
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/null_aware_chain.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+class Class {
+ Class get getter1 => this;
+ Class? get getter2 => field;
+ Class? field;
+ Class([this.field]);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/null_aware_chain.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/null_aware_chain.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f928776
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/null_aware_chain.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+class Class {
+ Class get getter1 => this;
+ Class([this.field]);
+ Class? field;
+ Class? get getter2 => field;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/null_check.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/null_check.dart.textual_outline.expect
new file mode 100644
index 0000000..e1ed616
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/null_check.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class Class {
+ int? field;
+ int? method() => field;
+ Class operator +(Class other) => new Class();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/null_check.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/null_check.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fb8764d
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/null_check.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class Class {
+ Class operator +(Class other) => new Class();
+ int? field;
+ int? method() => field;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/null_check_context.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/null_check_context.dart.textual_outline.expect
new file mode 100644
index 0000000..770d7e9
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/null_check_context.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+abstract class A {
+ T bar<T>();
+ String foo() => bar()!;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/null_check_context.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/null_check_context.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c26a712
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/null_check_context.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+abstract class A {
+ String foo() => bar()!;
+ T bar<T>();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/null_shorting.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/null_shorting.dart.textual_outline.expect
new file mode 100644
index 0000000..9527be1
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/null_shorting.dart.textual_outline.expect
@@ -0,0 +1,39 @@
+class Class1 {
+ Class1? get property => null;
+ void set property(Class1? value) {}
+ Class1 get property1 => new Class1();
+ Class2 get property2 => new Class2();
+ Class1? get nullable1 => property1;
+ void set nullable1(Class1? value) {}
+ Class1 nonNullable1Method() => nonNullable1;
+ Class1? operator [](Class1? key) => nullable1;
+ void operator []=(Class1? key, Class1? value) {}
+ Class1? operator +(int value) => nullable1;
+ Class1? operator -() => nullable1;
+ Class1 get nonNullable1 => property1;
+ Class2 get nonNullable2 => property2;
+}
+
+class Class2 {
+ Class2 get property => this;
+ void set property(Class2 value) {}
+ Class2 nonNullable2Method() => nonNullable2;
+ Class2 operator [](Class2? key) => property;
+ void operator []=(Class2? key, Class2? value) => property;
+ Class2 operator +(int value) => property;
+ Class2 operator -() => property;
+ Class2 get nonNullable2 => property;
+ void set nonNullable2(Class2 value) {}
+}
+
+class Class3 {
+ Class2? get property => null;
+ Class2? operator [](Class3? key) => property;
+}
+
+main() {}
+void propertyAccess(Class1? n1) {}
+void indexAccess(Class1? n1, Class2? n2, Class3? n3) {}
+void operatorAccess(Class1? n1, Class2? n2) {}
+void ifNull(Class1? n1) {}
+void throws(void Function() f) {}
diff --git a/pkg/front_end/testcases/nnbd/null_shorting.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/null_shorting.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..99a428a
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/null_shorting.dart.textual_outline_modelled.expect
@@ -0,0 +1,39 @@
+class Class1 {
+ Class1 get nonNullable1 => property1;
+ Class1 get property1 => new Class1();
+ Class1 nonNullable1Method() => nonNullable1;
+ Class1? get nullable1 => property1;
+ Class1? get property => null;
+ Class1? operator +(int value) => nullable1;
+ Class1? operator -() => nullable1;
+ Class1? operator [](Class1? key) => nullable1;
+ Class2 get nonNullable2 => property2;
+ Class2 get property2 => new Class2();
+ void operator []=(Class1? key, Class1? value) {}
+ void set nullable1(Class1? value) {}
+ void set property(Class1? value) {}
+}
+
+class Class2 {
+ Class2 get nonNullable2 => property;
+ Class2 get property => this;
+ Class2 nonNullable2Method() => nonNullable2;
+ Class2 operator +(int value) => property;
+ Class2 operator -() => property;
+ Class2 operator [](Class2? key) => property;
+ void operator []=(Class2? key, Class2? value) => property;
+ void set nonNullable2(Class2 value) {}
+ void set property(Class2 value) {}
+}
+
+class Class3 {
+ Class2? get property => null;
+ Class2? operator [](Class3? key) => property;
+}
+
+main() {}
+void ifNull(Class1? n1) {}
+void indexAccess(Class1? n1, Class2? n2, Class3? n3) {}
+void operatorAccess(Class1? n1, Class2? n2) {}
+void propertyAccess(Class1? n1) {}
+void throws(void Function() f) {}
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.textual_outline.expect
new file mode 100644
index 0000000..fded929
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class Class {
+ Class method() => this;
+}
+extension Extension ;
+on Class (){ }
+main() { }
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.textual_outline.expect
new file mode 100644
index 0000000..40fda8b
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.textual_outline.expect
@@ -0,0 +1,25 @@
+class Class1 {
+ Class1? get property => null;
+ void set property(Class1? value) { }
+ Class1 get property1 => new Class1();
+ Class2 get property2 => new Class2();
+}
+extension Extension1 ;
+on Class1 (){ }
+class Class2 {
+ Class2 get property => this;
+ void set property(Class2 value) { }
+}
+extension Extension2 ;
+on Class2 (){ }
+class Class3 {
+ Class2? get property => null;
+}
+extension Extension3 ;
+on Class3 (){ }
+main() { }
+void propertyAccess(Class1? n1) { }
+void indexAccess(Class1? n1, Class2? n2, Class3? n3) { }
+void operatorAccess(Class1? n1, Class2? n2) { }
+void ifNull(Class1? n1) { }
+void throws(void Function() f) { }
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.textual_outline.expect
new file mode 100644
index 0000000..40fda8b
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.textual_outline.expect
@@ -0,0 +1,25 @@
+class Class1 {
+ Class1? get property => null;
+ void set property(Class1? value) { }
+ Class1 get property1 => new Class1();
+ Class2 get property2 => new Class2();
+}
+extension Extension1 ;
+on Class1 (){ }
+class Class2 {
+ Class2 get property => this;
+ void set property(Class2 value) { }
+}
+extension Extension2 ;
+on Class2 (){ }
+class Class3 {
+ Class2? get property => null;
+}
+extension Extension3 ;
+on Class3 (){ }
+main() { }
+void propertyAccess(Class1? n1) { }
+void indexAccess(Class1? n1, Class2? n2, Class3? n3) { }
+void operatorAccess(Class1? n1, Class2? n2) { }
+void ifNull(Class1? n1) { }
+void throws(void Function() f) { }
diff --git a/pkg/front_end/testcases/nnbd/null_shorting_index.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/null_shorting_index.dart.textual_outline.expect
new file mode 100644
index 0000000..3e754ed
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/null_shorting_index.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class Class1 {
+ Class2? get field => null;
+ int operator [](int index) => index;
+ void operator []=(int index, int value) { }
+}
+class Class2 {
+ int field = 42;
+}
+extension Extension ;
+on Class2 (){ }
+main() { }
diff --git a/pkg/front_end/testcases/nnbd/nullable_access.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/nullable_access.dart.textual_outline.expect
new file mode 100644
index 0000000..a391c65
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_access.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+class Class {
+ A nonNullableField = const A();
+ A get nonNullableProperty => nonNullableField;
+ void set nonNullableProperty(A value) {}
+ A nonNullableMethod() => nonNullableField;
+}
+
+class A {
+ const A();
+ A get nonNullableProperty => this;
+}
+
+main() {}
+expect(expected, actual) {}
+throws(void Function() f) {}
diff --git a/pkg/front_end/testcases/nnbd/nullable_access.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/nullable_access.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..eed27fc
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_access.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+class A {
+ A get nonNullableProperty => this;
+ const A();
+}
+
+class Class {
+ A get nonNullableProperty => nonNullableField;
+ A nonNullableField = const A();
+ A nonNullableMethod() => nonNullableField;
+ void set nonNullableProperty(A value) {}
+}
+
+expect(expected, actual) {}
+main() {}
+throws(void Function() f) {}
diff --git a/pkg/front_end/testcases/nnbd/nullable_null.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/nullable_null.dart.textual_outline.expect
new file mode 100644
index 0000000..24bba59
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_null.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class A<X> {}
+
+class B extends A<Null> {}
+
+class C {
+ Null foo(Null n, A<Null> an) => n;
+}
+
+foo() {}
+bar() {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/nullable_null.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/nullable_null.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..604b26f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_null.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+bar() {}
+
+class A<X> {}
+
+class B extends A<Null> {}
+
+class C {
+ Null foo(Null n, A<Null> an) => n;
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/nullable_object_access.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/nullable_object_access.dart.textual_outline.expect
new file mode 100644
index 0000000..c224a86
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_object_access.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+abstract class CustomType extends Type {
+ void call() {}
+}
+
+abstract class CustomInvocation implements Invocation {}
+
+abstract class Class {
+ CustomType get runtimeType;
+ String noSuchMethod(covariant CustomInvocation invocation);
+ bool operator ==(covariant Class o);
+ String toString({Object o});
+}
+
+main() {}
+void test(Class c1, Class? c2, Invocation invocation,
+ CustomInvocation customInvocation) {}
diff --git a/pkg/front_end/testcases/nnbd/nullable_object_access.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/nullable_object_access.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b6a6c78
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_object_access.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+abstract class Class {
+ CustomType get runtimeType;
+ String noSuchMethod(covariant CustomInvocation invocation);
+ String toString({Object o});
+ bool operator ==(covariant Class o);
+}
+
+abstract class CustomInvocation implements Invocation {}
+
+abstract class CustomType extends Type {
+ void call() {}
+}
+
+main() {}
+void test(Class c1, Class? c2, Invocation invocation,
+ CustomInvocation customInvocation) {}
diff --git a/pkg/front_end/testcases/nnbd/nullable_param.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/nullable_param.dart.textual_outline.expect
new file mode 100644
index 0000000..3d0a427
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_param.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class Foo {
+ int? field;
+ int? bar(int? x) {}
+}
+
+main() {}
+int test_nullable_function_type_formal_param({int f()?: null}) {}
diff --git a/pkg/front_end/testcases/nnbd/nullable_param.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/nullable_param.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..307c9d6
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_param.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class Foo {
+ int? bar(int? x) {}
+ int? field;
+}
+
+int test_nullable_function_type_formal_param({int f()?: null}) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/nullable_receiver.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/nullable_receiver.dart.textual_outline.expect
new file mode 100644
index 0000000..b676129
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_receiver.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+class A {
+ foo() {}
+ int get bar => 42;
+ void set baz(int value) {}
+ void call() {}
+}
+
+class B {
+ String toString([int extra = 42]) => super.toString();
+}
+
+error(String? s, A? a, B? b) {}
+ok<T extends Object?>(String? s, A? a, T t, B? b, Invocation i) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/nullable_receiver.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/nullable_receiver.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d77e911
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_receiver.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+class A {
+ foo() {}
+ int get bar => 42;
+ void call() {}
+ void set baz(int value) {}
+}
+
+class B {
+ String toString([int extra = 42]) => super.toString();
+}
+
+error(String? s, A? a, B? b) {}
+main() {}
+ok<T extends Object?>(String? s, A? a, T t, B? b, Invocation i) {}
diff --git a/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart.textual_outline.expect
new file mode 100644
index 0000000..a732d24
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+typedef F = void Function()?;
+void foo(void Function() x) {}
+void bar(F x) {}
+void baz(F? x) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..091d52a
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_rhs_of_typedef.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+main() {}
+typedef F = void Function()?;
+void bar(F x) {}
+void baz(F? x) {}
+void foo(void Function() x) {}
diff --git a/pkg/front_end/testcases/nnbd/opt_out.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/opt_out.dart.textual_outline.expect
new file mode 100644
index 0000000..78cc73c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/opt_out.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+import 'opt_out_lib.dart';
+class A<T> {
+ late int ;
+ field = 42;
+}
+class B extends A<String?> {
+}
+typedef F = void Function()?;
+List<String?> l = [];
+String? s = null;
+var t = s!;
+late int ;
+field = 42;
+void method(void f()?, {required int a}) { }
+main() { }
+noErrors() { }
diff --git a/pkg/front_end/testcases/nnbd/override_checks.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/override_checks.dart.textual_outline.expect
new file mode 100644
index 0000000..6b2ec3c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/override_checks.dart.textual_outline.expect
@@ -0,0 +1,26 @@
+class A<X extends num> {}
+
+class B1 {
+ void set bar(num? value) {}
+ num get baz => 42;
+ void hest(num? value) {}
+}
+
+class B2 extends B1 {
+ num bar = 3.14;
+ num? get baz => null;
+ void hest(num value) {}
+}
+
+class C1 {
+ factory C1() = C2<int?>;
+}
+
+class C2<X extends int> implements C1 {}
+
+class D {
+ D.foo(num x);
+ factory D.bar(num? x) = D.foo;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/override_checks.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/override_checks.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c0742df
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/override_checks.dart.textual_outline_modelled.expect
@@ -0,0 +1,26 @@
+class A<X extends num> {}
+
+class B1 {
+ num get baz => 42;
+ void hest(num? value) {}
+ void set bar(num? value) {}
+}
+
+class B2 extends B1 {
+ num bar = 3.14;
+ num? get baz => null;
+ void hest(num value) {}
+}
+
+class C1 {
+ factory C1() = C2<int?>;
+}
+
+class C2<X extends int> implements C1 {}
+
+class D {
+ D.foo(num x);
+ factory D.bar(num? x) = D.foo;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/platform_definite_assignment/main.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/platform_definite_assignment/main.dart.textual_outline.expect
new file mode 100644
index 0000000..3c9c90e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/platform_definite_assignment/main.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+import 'dart:test';
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/platform_definite_assignment/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/platform_definite_assignment/main.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3c9c90e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/platform_definite_assignment/main.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+import 'dart:test';
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/platform_nonnullable_fields/main.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/platform_nonnullable_fields/main.dart.textual_outline.expect
new file mode 100644
index 0000000..3c9c90e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/platform_nonnullable_fields/main.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+import 'dart:test';
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/platform_nonnullable_fields/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/platform_nonnullable_fields/main.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3c9c90e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/platform_nonnullable_fields/main.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+import 'dart:test';
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/platform_optional_parameters/main.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/platform_optional_parameters/main.dart.textual_outline.expect
new file mode 100644
index 0000000..3c9c90e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/platform_optional_parameters/main.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+import 'dart:test';
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/platform_optional_parameters/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/platform_optional_parameters/main.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3c9c90e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/platform_optional_parameters/main.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+import 'dart:test';
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart.textual_outline.expect
new file mode 100644
index 0000000..dca172b
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart.textual_outline.expect
@@ -0,0 +1,31 @@
+const num three = 3;
+dynamic dynamicFunction(dynamic d) => d;
+Object? objectFunction(Object? o) => o;
+int intFunction(int i) => i;
+T idFunction<T>(T t) => t;
+const int Function(int) idAsIntFunction = idFunction;
+
+class Class<T> {
+ final T field;
+ const Class(dynamic value) : field = value as T;
+}
+
+class ClassWithBound<T extends num> {
+ final T field;
+ const ClassWithBound() : field = three as T;
+ const ClassWithBound.withValue(dynamic value) : field = value as T;
+}
+
+class ClassWithList<T> {
+ final List<T> field;
+ const ClassWithList(dynamic value) : field = value as List<T>;
+}
+
+class ClassWithFunction<T> {
+ final T Function(T) field;
+ const ClassWithFunction(dynamic value) : field = value as T Function(T);
+}
+
+void main() {}
+weakMode() {}
+errors() {}
diff --git a/pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9241bde
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/potentially_constant_type_as.dart.textual_outline_modelled.expect
@@ -0,0 +1,31 @@
+Object? objectFunction(Object? o) => o;
+T idFunction<T>(T t) => t;
+
+class Class<T> {
+ const Class(dynamic value) : field = value as T;
+ final T field;
+}
+
+class ClassWithBound<T extends num> {
+ const ClassWithBound() : field = three as T;
+ const ClassWithBound.withValue(dynamic value) : field = value as T;
+ final T field;
+}
+
+class ClassWithFunction<T> {
+ const ClassWithFunction(dynamic value) : field = value as T Function(T);
+ final T Function(T) field;
+}
+
+class ClassWithList<T> {
+ const ClassWithList(dynamic value) : field = value as List<T>;
+ final List<T> field;
+}
+
+const int Function(int) idAsIntFunction = idFunction;
+const num three = 3;
+dynamic dynamicFunction(dynamic d) => d;
+errors() {}
+int intFunction(int i) => i;
+void main() {}
+weakMode() {}
diff --git a/pkg/front_end/testcases/nnbd/potentially_constant_type_is.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/potentially_constant_type_is.dart.textual_outline.expect
new file mode 100644
index 0000000..1fb936c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/potentially_constant_type_is.dart.textual_outline.expect
@@ -0,0 +1,29 @@
+const num three = 3;
+dynamic dynamicFunction(dynamic d) => d;
+Object? objectFunction(Object? o) => o;
+int intFunction(int i) => i;
+T idFunction<T>(T t) => t;
+const int Function(int) idAsIntFunction = idFunction;
+
+class Class<T> {
+ final bool field;
+ const Class(dynamic value) : field = value is T;
+}
+
+class ClassWithBound<T extends num> {
+ final bool field;
+ const ClassWithBound() : field = three is T;
+ const ClassWithBound.withValue(dynamic value) : field = value is T;
+}
+
+class ClassWithList<T> {
+ final bool field;
+ const ClassWithList(dynamic value) : field = value is List<T>;
+}
+
+class ClassWithFunction<T> {
+ final bool field;
+ const ClassWithFunction(dynamic value) : field = value is T Function(T);
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/nnbd/potentially_constant_type_is.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/potentially_constant_type_is.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5ee4178
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/potentially_constant_type_is.dart.textual_outline_modelled.expect
@@ -0,0 +1,29 @@
+Object? objectFunction(Object? o) => o;
+T idFunction<T>(T t) => t;
+
+class Class<T> {
+ const Class(dynamic value) : field = value is T;
+ final bool field;
+}
+
+class ClassWithBound<T extends num> {
+ const ClassWithBound() : field = three is T;
+ const ClassWithBound.withValue(dynamic value) : field = value is T;
+ final bool field;
+}
+
+class ClassWithFunction<T> {
+ const ClassWithFunction(dynamic value) : field = value is T Function(T);
+ final bool field;
+}
+
+class ClassWithList<T> {
+ const ClassWithList(dynamic value) : field = value is List<T>;
+ final bool field;
+}
+
+const int Function(int) idAsIntFunction = idFunction;
+const num three = 3;
+dynamic dynamicFunction(dynamic d) => d;
+int intFunction(int i) => i;
+void main() {}
diff --git a/pkg/front_end/testcases/nnbd/potentially_non_nullable_field.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/potentially_non_nullable_field.dart.textual_outline.expect
new file mode 100644
index 0000000..b745878
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/potentially_non_nullable_field.dart.textual_outline.expect
@@ -0,0 +1,25 @@
+int x;
+int? y;
+late int ;
+z;
+class A<T extends Object?> {
+ static int x;
+ static int? y;
+ static late int ;
+ z;
+ int lx;
+ int? ly;
+ late int;
+ operator? ( ){ }
+ lz;
+ int lv;
+ int lu;
+ T lt;
+ T? ls;
+ late T ;
+ lr;
+ T lp;
+ T lq;
+ A(this.lv, this.lp, T t) : this.lu = 42, this.lq = t;
+}
+main() { }
diff --git a/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.textual_outline.expect
new file mode 100644
index 0000000..05e9dc0
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/potentially_nullable_access.dart.textual_outline.expect
@@ -0,0 +1,52 @@
+class Class {
+ int property = 0;
+ int method() => 0;
+ Function functionField = () {};
+ void Function() functionTypeField = () {};
+ Function get functionGetter => () {};
+ void Function() get functionTypeGetter => () {};
+}
+extension Extension ;
+on Class (){ }
+Function? get nullableFunction => () {};
+void Function()? get nullableFunctionType => () {};
+int? get nullableInt => 0;
+Map<dynamic, dynamic>? get nullableMap => {};
+Class? get nullableClass => new Class();
+var topLevelBinary = nullableInt + 0;
+var topLevelUnary = -nullableInt;
+var topLevelIndexGet = nullableMap[0];
+var topLevelIndexSet = nullableMap[0] = 1;
+var topLevelIndexGetSet = nullableMap[0] += 1;
+var topLevelPropertyGet = nullableClass.property;
+var topLevelPropertySet = nullableClass.property = 1;
+var topLevelPropertyGetSet = nullableClass.property += 1;
+var topLevelMethodInvocation = nullableClass.method();
+var topLevelMethodTearOff = nullableClass.method;
+var topLevelFunctionImplicitCall = nullableFunction();
+var topLevelFunctionExplicitCall = nullableFunction.call();
+var topLevelFunctionTearOff = nullableFunction.call;
+var topLevelFunctionTypeImplicitCall = nullableFunctionType();
+var topLevelFunctionTypeExplicitCall = nullableFunctionType.call();
+var topLevelFunctionTypeTearOff = nullableFunctionType.call;
+var topLevelFunctionField = nullableClass.functionField();
+var topLevelFunctionTypeField = nullableClass.functionTypeField();
+var topLevelFunctionGetter = nullableClass.functionGetter();
+var topLevelFunctionTypeGetter = nullableClass.functionTypeGetter();
+var topLevelExtensionBinary = nullableClass + 0;
+var topLevelExtensionUnary = -nullableClass;
+var topLevelExtensionIndexGet = nullableClass[0];
+var topLevelExtensionIndexSet = nullableClass[0] = 1;
+var topLevelExtensionIndexGetSet = nullableClass[0] += 1;
+var topLevelExtensionPropertyGet = nullableClass.extensionProperty;
+var topLevelExtensionPropertySet = nullableClass.extensionProperty = 1;
+var topLevelExtensionPropertyGetSet = nullableClass.extensionProperty += 1;
+var topLevelExtensionMethodInvocation = nullableClass.extensionMethod();
+var topLevelExtensionMethodTearOff = nullableClass.extensionMethod;
+var topLevelExtensionFunctionTypeImplicitCall = nullableClass();
+var topLevelExtensionFunctionTypeExplicitCall = nullableClass.call();
+var topLevelExtensionFunctionTypeTearOff = nullableClass.call;
+var topLevelExtensionFunctionGetter = nullableClass.extensionFunctionGetter();
+var topLevelExtensionFunctionTypeGetter = nullableClass.extensionFunctionTypeGetter();
+test() { }
+main() { }
diff --git a/pkg/front_end/testcases/nnbd/regress_null_aware.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/regress_null_aware.dart.textual_outline.expect
new file mode 100644
index 0000000..c2626cd
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/regress_null_aware.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+class Class {
+ Map<String, Set<String>> map;
+ List<String> method(String node, Set<String> set) => set.add(node)
+ ? [node, ...?map[node]?.expand((node) => method(node, set))?.toList()]
+ : [];
+}
+
+main(args) {}
diff --git a/pkg/front_end/testcases/nnbd/regress_null_aware.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/regress_null_aware.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..655c194
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/regress_null_aware.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+// @dart = 2.6
+class Class {
+ List<String> method(String node, Set<String> set) => set.add(node)
+ ? [node, ...?map[node]?.expand((node) => method(node, set))?.toList()]
+ : [];
+ Map<String, Set<String>> map;
+}
+
+main(args) {}
diff --git a/pkg/front_end/testcases/nnbd/required.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/required.dart.textual_outline.expect
new file mode 100644
index 0000000..5ddcc25
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/required.dart.textual_outline.expect
@@ -0,0 +1,29 @@
+method({int a = 42, required int b, required final int c}) {}
+
+class Class {
+ method(
+ {int a = 42,
+ required int b,
+ required final int c,
+ required covariant final int d}) {}
+}
+
+typedef Typedef1 = Function({int a, required int b});
+typedef Typedef2({int a, required int b});
+Function({int a, required int b}) field = ({int a = 42, required int b}) {};
+
+abstract class A {
+ foo({int x});
+}
+
+class B extends A {
+ foo({x}) {}
+}
+
+class C extends A {
+ foo({x = 42}) {}
+}
+
+ok() {}
+error() {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/required.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/required.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c9af5d3
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/required.dart.textual_outline_modelled.expect
@@ -0,0 +1,28 @@
+Function({int a, required int b}) field = ({int a = 42, required int b}) {};
+
+abstract class A {
+ foo({int x});
+}
+
+class B extends A {
+ foo({x}) {}
+}
+
+class C extends A {
+ foo({x = 42}) {}
+}
+
+class Class {
+ method(
+ {int a = 42,
+ required int b,
+ required final int c,
+ required covariant final int d}) {}
+}
+
+error() {}
+main() {}
+method({int a = 42, required int b, required final int c}) {}
+ok() {}
+typedef Typedef1 = Function({int a, required int b});
+typedef Typedef2({int a, required int b});
diff --git a/pkg/front_end/testcases/nnbd/required_name_override.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/required_name_override.dart.textual_outline.expect
new file mode 100644
index 0000000..81c1483
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/required_name_override.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+import 'required_name_override_lib.dart';
+
+class B {
+ void test_default({int? i}) {}
+ void test_nondefault({int? i = 1}) {}
+}
+
+class A extends B implements C {
+ void test_default({required int? i}) {}
+ void test_nondefault({required int? i}) {}
+ void test_legacy({required int? i}) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/required_name_override.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/required_name_override.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8ad5428
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/required_name_override.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+import 'required_name_override_lib.dart';
+
+class A extends B implements C {
+ void test_default({required int? i}) {}
+ void test_legacy({required int? i}) {}
+ void test_nondefault({required int? i}) {}
+}
+
+class B {
+ void test_default({int? i}) {}
+ void test_nondefault({int? i = 1}) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/required_named_parameter.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/required_named_parameter.dart.textual_outline.expect
new file mode 100644
index 0000000..63a8f9e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/required_named_parameter.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+foo({required int parameter = 42}) {}
+foo2({int parameter}) {}
+foo3([int parameter]) {}
+bar({required int parameter}) {}
+bar2({int parameter = 42}) {}
+bar3([int parameter = 42]) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/required_named_parameter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/required_named_parameter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9a48b7f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/required_named_parameter.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+bar({required int parameter}) {}
+bar2({int parameter = 42}) {}
+bar3([int parameter = 42]) {}
+foo({required int parameter = 42}) {}
+foo2({int parameter}) {}
+foo3([int parameter]) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/return_late.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/return_late.dart.textual_outline.expect
new file mode 100644
index 0000000..3d93fd2
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/return_late.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class Class<E> {
+ final E field;
+ Class(this.field);
+ E returnTypeVariable() {}
+}
+
+int returnNonNullable(int value) {}
+int? returnNullable(int? value) {}
+main() {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/nnbd/return_late.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/return_late.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e1ef11f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/return_late.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+class Class<E> {
+ Class(this.field);
+ E returnTypeVariable() {}
+ final E field;
+}
+
+expect(expected, actual) {}
+int returnNonNullable(int value) {}
+int? returnNullable(int? value) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/return_null.dart.strong.expect b/pkg/front_end/testcases/nnbd/return_null.dart.strong.expect
index 336e616..f5bbf44 100644
--- a/pkg/front_end/testcases/nnbd/return_null.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/return_null.dart.strong.expect
@@ -6,11 +6,11 @@
// String returnImplicit() /*error*/ {
// ^
//
-// pkg/front_end/testcases/nnbd/return_null.dart:13:10: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/nnbd/return_null.dart:13:10: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
// return null; // error
// ^
//
-// pkg/front_end/testcases/nnbd/return_null.dart:19:12: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/nnbd/return_null.dart:19:12: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
// return null; // error
// ^
//
@@ -31,11 +31,11 @@
// String returnImplicit() /* error */ {
// ^
//
-// pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
// return null; // error
// ^
//
-// pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
// return null; // error
// ^
//
@@ -82,14 +82,14 @@
}
static method returnExplicit() → core::String {
core::print("foo");
- return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:13:10: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+ return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:13:10: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
return null; // error
^" in null as{TypeError,ForNonNullableByDefault} core::String;
}
static method returnMixed(core::bool b) → core::String {
if(b) {
core::print("foo");
- return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:19:12: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+ return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:19:12: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
return null; // error
^" in null as{TypeError,ForNonNullableByDefault} core::String;
}
@@ -151,14 +151,14 @@
}
function returnExplicit() → core::String {
core::print("foo");
- return let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+ return let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
return null; // error
^" in null as{TypeError,ForNonNullableByDefault} core::String;
}
function returnMixed(core::bool b) → core::String {
if(b) {
core::print("foo");
- return let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+ return let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
return null; // error
^" in null as{TypeError,ForNonNullableByDefault} core::String;
}
diff --git a/pkg/front_end/testcases/nnbd/return_null.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/return_null.dart.strong.transformed.expect
index bdf53ff..1b65644 100644
--- a/pkg/front_end/testcases/nnbd/return_null.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/return_null.dart.strong.transformed.expect
@@ -6,11 +6,11 @@
// String returnImplicit() /*error*/ {
// ^
//
-// pkg/front_end/testcases/nnbd/return_null.dart:13:10: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/nnbd/return_null.dart:13:10: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
// return null; // error
// ^
//
-// pkg/front_end/testcases/nnbd/return_null.dart:19:12: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/nnbd/return_null.dart:19:12: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
// return null; // error
// ^
//
@@ -31,11 +31,11 @@
// String returnImplicit() /* error */ {
// ^
//
-// pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
// return null; // error
// ^
//
-// pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
// return null; // error
// ^
//
@@ -82,14 +82,14 @@
}
static method returnExplicit() → core::String {
core::print("foo");
- return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:13:10: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+ return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:13:10: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
return null; // error
^" in null as{TypeError,ForNonNullableByDefault} core::String;
}
static method returnMixed(core::bool b) → core::String {
if(b) {
core::print("foo");
- return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:19:12: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+ return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:19:12: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
return null; // error
^" in null as{TypeError,ForNonNullableByDefault} core::String;
}
@@ -349,14 +349,14 @@
}
function returnExplicit() → core::String {
core::print("foo");
- return let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+ return let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
return null; // error
^" in null as{TypeError,ForNonNullableByDefault} core::String;
}
function returnMixed(core::bool b) → core::String {
if(b) {
core::print("foo");
- return let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+ return let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
return null; // error
^" in null as{TypeError,ForNonNullableByDefault} core::String;
}
diff --git a/pkg/front_end/testcases/nnbd/return_null.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/return_null.dart.textual_outline.expect
new file mode 100644
index 0000000..0823c8f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/return_null.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+import 'dart:async';
+
+String returnImplicit() {}
+String returnExplicit() {}
+String returnMixed(bool b) {}
+Future returnAsync1() async {}
+FutureOr returnAsync2() async {}
+FutureOr<int> returnAsync3() async {}
+FutureOr<int?> returnAsync4() async {}
+returnAsync5() async {}
+Future<int?> returnAsync6() async {}
+Future<int?> returnAsync7() async {}
+Iterable yieldSync() sync* {}
+Stream yieldAsync() async* {}
+enum Enum { a, b }
+Enum caseReturn1(Enum e) {}
+Enum caseReturn2(Enum e) {}
+localFunctions() {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/return_null.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/return_null.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5d7cbcb6
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/return_null.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+import 'dart:async';
+
+Enum caseReturn1(Enum e) {}
+Enum caseReturn2(Enum e) {}
+Future returnAsync1() async {}
+Future<int?> returnAsync6() async {}
+Future<int?> returnAsync7() async {}
+FutureOr returnAsync2() async {}
+FutureOr<int> returnAsync3() async {}
+FutureOr<int?> returnAsync4() async {}
+Iterable yieldSync() sync* {}
+Stream yieldAsync() async* {}
+String returnExplicit() {}
+String returnImplicit() {}
+String returnMixed(bool b) {}
+enum Enum { a, b }
+localFunctions() {}
+main() {}
+returnAsync5() async {}
diff --git a/pkg/front_end/testcases/nnbd/return_null.dart.weak.expect b/pkg/front_end/testcases/nnbd/return_null.dart.weak.expect
index 9180305..397d54c 100644
--- a/pkg/front_end/testcases/nnbd/return_null.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/return_null.dart.weak.expect
@@ -6,11 +6,11 @@
// String returnImplicit() /*error*/ {
// ^
//
-// pkg/front_end/testcases/nnbd/return_null.dart:13:10: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/nnbd/return_null.dart:13:10: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
// return null; // error
// ^
//
-// pkg/front_end/testcases/nnbd/return_null.dart:19:12: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/nnbd/return_null.dart:19:12: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
// return null; // error
// ^
//
@@ -31,11 +31,11 @@
// String returnImplicit() /* error */ {
// ^
//
-// pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
// return null; // error
// ^
//
-// pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
// return null; // error
// ^
//
@@ -82,14 +82,14 @@
}
static method returnExplicit() → core::String {
core::print("foo");
- return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:13:10: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+ return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:13:10: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
return null; // error
^" in null as{TypeError,ForNonNullableByDefault} core::String;
}
static method returnMixed(core::bool b) → core::String {
if(b) {
core::print("foo");
- return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:19:12: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+ return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:19:12: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
return null; // error
^" in null as{TypeError,ForNonNullableByDefault} core::String;
}
@@ -151,14 +151,14 @@
}
function returnExplicit() → core::String {
core::print("foo");
- return let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+ return let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
return null; // error
^" in null as{TypeError,ForNonNullableByDefault} core::String;
}
function returnMixed(core::bool b) → core::String {
if(b) {
core::print("foo");
- return let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+ return let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
return null; // error
^" in null as{TypeError,ForNonNullableByDefault} core::String;
}
diff --git a/pkg/front_end/testcases/nnbd/return_null.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/return_null.dart.weak.transformed.expect
index ce589a6..a41a122 100644
--- a/pkg/front_end/testcases/nnbd/return_null.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/return_null.dart.weak.transformed.expect
@@ -6,11 +6,11 @@
// String returnImplicit() /*error*/ {
// ^
//
-// pkg/front_end/testcases/nnbd/return_null.dart:13:10: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/nnbd/return_null.dart:13:10: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
// return null; // error
// ^
//
-// pkg/front_end/testcases/nnbd/return_null.dart:19:12: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/nnbd/return_null.dart:19:12: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
// return null; // error
// ^
//
@@ -31,11 +31,11 @@
// String returnImplicit() /* error */ {
// ^
//
-// pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
// return null; // error
// ^
//
-// pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
// return null; // error
// ^
//
@@ -82,14 +82,14 @@
}
static method returnExplicit() → core::String {
core::print("foo");
- return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:13:10: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+ return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:13:10: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
return null; // error
^" in null as{TypeError,ForNonNullableByDefault} core::String;
}
static method returnMixed(core::bool b) → core::String {
if(b) {
core::print("foo");
- return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:19:12: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+ return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:19:12: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
return null; // error
^" in null as{TypeError,ForNonNullableByDefault} core::String;
}
@@ -349,14 +349,14 @@
}
function returnExplicit() → core::String {
core::print("foo");
- return let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+ return let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
return null; // error
^" in null as{TypeError,ForNonNullableByDefault} core::String;
}
function returnMixed(core::bool b) → core::String {
if(b) {
core::print("foo");
- return let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: A value of type 'Null?' can't be assigned to a variable of type 'String'.
+ return let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: A value of type 'Null' can't be assigned to a variable of type 'String'.
return null; // error
^" in null as{TypeError,ForNonNullableByDefault} core::String;
}
diff --git a/pkg/front_end/testcases/nnbd/shorting_stop.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/shorting_stop.dart.textual_outline.expect
new file mode 100644
index 0000000..2b0383f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/shorting_stop.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+class Class {
+ int field = 0;
+ Class get next => this;
+ int operator [](int key) => key;
+ void operator []=(int key, int value) {}
+}
+
+main() {}
+test(Class? c) {}
+final bool inStrongMode = _inStrongMode();
+bool _inStrongMode() {}
+void throwsInStrong(void Function() f) {}
diff --git a/pkg/front_end/testcases/nnbd/shorting_stop.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/shorting_stop.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..704a646
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/shorting_stop.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+bool _inStrongMode() {}
+
+class Class {
+ Class get next => this;
+ int field = 0;
+ int operator [](int key) => key;
+ void operator []=(int key, int value) {}
+}
+
+final bool inStrongMode = _inStrongMode();
+main() {}
+test(Class? c) {}
+void throwsInStrong(void Function() f) {}
diff --git a/pkg/front_end/testcases/nnbd/simple_never.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/simple_never.dart.textual_outline.expect
new file mode 100644
index 0000000..a729e48
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/simple_never.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+Never foo() {}
+Never? bar() => null;
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/simple_never.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/simple_never.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a729e48
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/simple_never.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+Never foo() {}
+Never? bar() => null;
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/sink_hierarchy.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/sink_hierarchy.dart.textual_outline.expect
new file mode 100644
index 0000000..920e335
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/sink_hierarchy.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+// @dart = 2.6
+abstract class Sink<T> {
+ void close();
+}
+
+abstract class EventSink<T> implements Sink<T> {
+ void close();
+}
+
+abstract class StreamConsumer<S> {
+ Future close();
+}
+
+abstract class StreamSink<S> implements EventSink<S>, StreamConsumer<S> {
+ Future close();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/sink_hierarchy.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/sink_hierarchy.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3b450f4
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/sink_hierarchy.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+// @dart = 2.6
+abstract class EventSink<T> implements Sink<T> {
+ void close();
+}
+
+abstract class Sink<T> {
+ void close();
+}
+
+abstract class StreamConsumer<S> {
+ Future close();
+}
+
+abstract class StreamSink<S> implements EventSink<S>, StreamConsumer<S> {
+ Future close();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.textual_outline.expect
new file mode 100644
index 0000000..9aff973
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/strictly_non_nullable_warnings.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+extension E ;
+on String (){ }
+class A {
+ String operator[](int index) => "foo";
+ void operator[]=(int index, String value) { }
+}
+class B extends A {
+ void test() { }
+}
+warning(String s, List<String> l, Map<String, int> m) { }
+main() { }
diff --git a/pkg/front_end/testcases/nnbd/substitution_in_inference.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/substitution_in_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..c248ef3
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/substitution_in_inference.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+foo<T extends Object?, S extends List<T>>(T t) => null;
+bar<T extends Object?, S extends List<T?>>(T t) => null;
+baz(int? x, int y) {}
+
+class A<T extends Object?, S extends Object> {
+ hest<X extends T, Y extends List<X>, Z extends List<X?>>() => null;
+ fisk<X extends S, Y extends List<X>, Z extends List<X?>>() => null;
+ mus<X extends Object?, Y extends List<X>, Z extends List<X?>>() => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/substitution_in_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/substitution_in_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ca5c31e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/substitution_in_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+bar<T extends Object?, S extends List<T?>>(T t) => null;
+baz(int? x, int y) {}
+
+class A<T extends Object?, S extends Object> {
+ fisk<X extends S, Y extends List<X>, Z extends List<X?>>() => null;
+ hest<X extends T, Y extends List<X>, Z extends List<X?>>() => null;
+ mus<X extends Object?, Y extends List<X>, Z extends List<X?>>() => null;
+}
+
+foo<T extends Object?, S extends List<T>>(T t) => null;
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/switch_redesign_fall_over.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/switch_redesign_fall_over.dart.textual_outline.expect
new file mode 100644
index 0000000..97c69c0
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/switch_redesign_fall_over.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+bar() {}
+foo(int x, bool b) {}
+
+abstract class A {
+ foo(int x, bool b) {}
+ Never neverReturn();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/switch_redesign_fall_over.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/switch_redesign_fall_over.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f92853d
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/switch_redesign_fall_over.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+abstract class A {
+ Never neverReturn();
+ foo(int x, bool b) {}
+}
+
+bar() {}
+foo(int x, bool b) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/switch_redesign_types.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/switch_redesign_types.dart.textual_outline.expect
new file mode 100644
index 0000000..02a881f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/switch_redesign_types.dart.textual_outline.expect
@@ -0,0 +1,20 @@
+class A {
+ final int foo;
+ const A(this.foo);
+}
+
+class B extends A {
+ const B(int foo) : super(foo);
+}
+
+class C extends B {
+ const C(int foo) : super(foo);
+}
+
+class D extends B {
+ const D(int foo) : super(foo);
+ bool operator ==(dynamic other) => identical(this, other);
+}
+
+bar(B b) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/switch_redesign_types.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/switch_redesign_types.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..49e84fe
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/switch_redesign_types.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+bar(B b) {}
+
+class A {
+ const A(this.foo);
+ final int foo;
+}
+
+class B extends A {
+ const B(int foo) : super(foo);
+}
+
+class C extends B {
+ const C(int foo) : super(foo);
+}
+
+class D extends B {
+ bool operator ==(dynamic other) => identical(this, other);
+ const D(int foo) : super(foo);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart.textual_outline.expect
new file mode 100644
index 0000000..81af6ded
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class C {
+ int call() => 0;
+}
+
+functionContext(int Function() f) {}
+nullableFunctionContext(int Function()? f) {}
+foo<T extends C?>(C? c, T t, T? nt) {}
+bar<T extends C>(C c, T t) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..16298a3
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/tearoff_from_nullable_receiver.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+bar<T extends C>(C c, T t) {}
+
+class C {
+ int call() => 0;
+}
+
+foo<T extends C?>(C? c, T t, T? nt) {}
+functionContext(int Function() f) {}
+main() {}
+nullableFunctionContext(int Function()? f) {}
diff --git a/pkg/front_end/testcases/nnbd/type_parameter_types.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/type_parameter_types.dart.textual_outline.expect
new file mode 100644
index 0000000..6350615
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/type_parameter_types.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+Never never() => throw "Never";
+
+class A<X extends Object, Y extends Object?> {
+ X foo() => never();
+ X? bar() => null;
+ Y baz() => never();
+}
+
+class B<X extends List<Y>, Y extends Object?> {
+ foo(X x, Y y) {}
+}
+
+class C<X extends List<Y>?, Y extends List<X>?> {
+ foo(X x, Y y) {}
+}
+
+class D<X extends Y, Y extends Z, Z> {
+ foo(X x, Y y, Z z) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/type_parameter_types.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/type_parameter_types.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6350615
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/type_parameter_types.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+Never never() => throw "Never";
+
+class A<X extends Object, Y extends Object?> {
+ X foo() => never();
+ X? bar() => null;
+ Y baz() => never();
+}
+
+class B<X extends List<Y>, Y extends Object?> {
+ foo(X x, Y y) {}
+}
+
+class C<X extends List<Y>?, Y extends List<X>?> {
+ foo(X x, Y y) {}
+}
+
+class D<X extends Y, Y extends Z, Z> {
+ foo(X x, Y y, Z z) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/uninitialized_non_nullable_late_fields.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/uninitialized_non_nullable_late_fields.dart.textual_outline.expect
new file mode 100644
index 0000000..86269fb
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/uninitialized_non_nullable_late_fields.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class A {
+ late int ;
+ x;
+ A.foo(this.x);
+ A.bar();
+}
+main() { }
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.textual_outline.expect
new file mode 100644
index 0000000..9333088
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+void expectTypeError(callback()) {}
+
+abstract class I {
+ int foo;
+}
+
+class A implements I {
+ dynamic noSuchMethod(i) => "bar";
+}
+
+class B extends A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d7487d5
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+abstract class I {
+ int foo;
+}
+
+class A implements I {
+ dynamic noSuchMethod(i) => "bar";
+}
+
+class B extends A {}
+
+main() {}
+void expectTypeError(callback()) {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in.dart.textual_outline.expect
new file mode 100644
index 0000000..0c3243c
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+int count = 0;
+
+abstract class A {
+ int foo;
+}
+
+class B implements A {
+ noSuchMethod(i) {}
+}
+
+class C extends Object with B {
+ int get foo => 42;
+ void set foo(int value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..95afa4a
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+abstract class A {
+ int foo;
+}
+
+class B implements A {
+ noSuchMethod(i) {}
+}
+
+class C extends Object with B {
+ int get foo => 42;
+ void set foo(int value) {}
+}
+
+int count = 0;
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.textual_outline.expect
new file mode 100644
index 0000000..0a9f2c8
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.textual_outline.expect
@@ -0,0 +1,21 @@
+void expectTypeError(callback()) {}
+
+abstract class A {
+ int foo;
+}
+
+abstract class B implements A {
+ int get foo => 42;
+ noSuchMethod(i) => "bar";
+}
+
+class C extends B {}
+
+abstract class D implements A {
+ void set foo(int value) {}
+ noSuchMethod(i) => "bar";
+}
+
+class E extends D {}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8f5c068
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.textual_outline_modelled.expect
@@ -0,0 +1,20 @@
+abstract class A {
+ int foo;
+}
+
+abstract class B implements A {
+ int get foo => 42;
+ noSuchMethod(i) => "bar";
+}
+
+abstract class D implements A {
+ noSuchMethod(i) => "bar";
+ void set foo(int value) {}
+}
+
+class C extends B {}
+
+class E extends D {}
+
+main() {}
+void expectTypeError(callback()) {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.textual_outline.expect
new file mode 100644
index 0000000..45fe92b
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+void expectTypeError(callback()) {}
+
+abstract class A<X> {
+ List<X> foo;
+}
+
+class B implements A<int> {
+ dynamic noSuchMethod(i) => <dynamic>[];
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..127e73c
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+abstract class A<X> {
+ List<X> foo;
+}
+
+class B implements A<int> {
+ dynamic noSuchMethod(i) => <dynamic>[];
+}
+
+main() {}
+void expectTypeError(callback()) {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.textual_outline.expect
new file mode 100644
index 0000000..43533ee
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class A {
+ dynamic noSuchMethod(Invocation i) {}
+}
+
+abstract class I {
+ void foo();
+}
+
+class B extends A implements I {}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..19f7e0e
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+abstract class I {
+ void foo();
+}
+
+class A {
+ dynamic noSuchMethod(Invocation i) {}
+}
+
+class B extends A implements I {}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_override_abstract_different_type.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_override_abstract_different_type.dart.textual_outline.expect
new file mode 100644
index 0000000..05bec89
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_override_abstract_different_type.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+class Base {
+ set push(int x);
+ set float(covariant int x);
+ noSuchMethod(i) => print("${runtimeType}: ${i.positionalArguments[0]}");
+}
+
+class Me extends Base {}
+
+class You extends Base {
+ set push(num x);
+ set float(num x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_override_abstract_different_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_override_abstract_different_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a9d0939
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_override_abstract_different_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+class Base {
+ noSuchMethod(i) => print("${runtimeType}: ${i.positionalArguments[0]}");
+ set float(covariant int x);
+ set push(int x);
+}
+
+class Me extends Base {}
+
+class You extends Base {
+ set float(num x);
+ set push(num x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_override_with_different_signature.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_override_with_different_signature.dart.textual_outline.expect
new file mode 100644
index 0000000..7882e0f
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_override_with_different_signature.dart.textual_outline.expect
@@ -0,0 +1,23 @@
+class Cat {
+ bool eatFood(String food) => true;
+}
+
+class MockCat implements Cat {
+ dynamic noSuchMethod(Invocation invocation) {}
+}
+
+class MockCat2 extends MockCat {
+ noSuchMethod(_);
+}
+
+class MockCat3 extends MockCat2 implements Cat {
+ bool eatFood(String food, {double amount});
+}
+
+class MockCat4 extends MockCat2 implements HungryCat {}
+
+abstract class HungryCat {
+ bool eatFood(String food, {double amount, double yetAnother});
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_override_with_different_signature.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_override_with_different_signature.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9db578e
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_override_with_different_signature.dart.textual_outline_modelled.expect
@@ -0,0 +1,23 @@
+abstract class HungryCat {
+ bool eatFood(String food, {double amount, double yetAnother});
+}
+
+class Cat {
+ bool eatFood(String food) => true;
+}
+
+class MockCat implements Cat {
+ dynamic noSuchMethod(Invocation invocation) {}
+}
+
+class MockCat2 extends MockCat {
+ noSuchMethod(_);
+}
+
+class MockCat3 extends MockCat2 implements Cat {
+ bool eatFood(String food, {double amount});
+}
+
+class MockCat4 extends MockCat2 implements HungryCat {}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application.dart.textual_outline.expect
new file mode 100644
index 0000000..d94d661
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+abstract class I {
+ foo();
+}
+
+class A {
+ foo() {}
+}
+
+class B implements I {
+ noSuchMethod(_) => null;
+}
+
+class C extends A with B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d94d661
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+abstract class I {
+ foo();
+}
+
+class A {
+ foo() {}
+}
+
+class B implements I {
+ noSuchMethod(_) => null;
+}
+
+class C extends A with B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/default_argument_values.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/default_argument_values.dart.textual_outline.expect
new file mode 100644
index 0000000..4af18d8
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/default_argument_values.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+abstract class A {
+ noSuchMethod(Invocation i) {}
+ String foo({String bar = "baz"});
+ int hest([int fisk = 42]);
+}
+
+class B extends A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/default_argument_values.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/default_argument_values.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5f49625
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/default_argument_values.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+abstract class A {
+ String foo({String bar = "baz"});
+ int hest([int fisk = 42]);
+ noSuchMethod(Invocation i) {}
+}
+
+class B extends A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/duplicated_abstract_method.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/duplicated_abstract_method.dart.textual_outline.expect
new file mode 100644
index 0000000..c5dc3c0
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/duplicated_abstract_method.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+abstract class I1 {
+ void foo();
+}
+
+abstract class I2 {
+ void foo();
+}
+
+class M implements I1, I2 {
+ dynamic noSuchMethod(Invocation i) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/duplicated_abstract_method.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/duplicated_abstract_method.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c5dc3c0
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/duplicated_abstract_method.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+abstract class I1 {
+ void foo();
+}
+
+abstract class I2 {
+ void foo();
+}
+
+class M implements I1, I2 {
+ dynamic noSuchMethod(Invocation i) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/forwarder_propagation.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/forwarder_propagation.dart.textual_outline.expect
new file mode 100644
index 0000000..aaadcb4
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/forwarder_propagation.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+import './forwarder_propagation_lib.dart';
+
+abstract class A {
+ void set foo(int value);
+ int get bar;
+ void baz(int x, {String y, double z});
+}
+
+class B implements A {
+ noSuchMethod(_) {}
+}
+
+class C extends B {}
+
+class E implements D {}
+
+class F extends E {}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/forwarder_propagation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/forwarder_propagation.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d3bb17c
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/forwarder_propagation.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+import './forwarder_propagation_lib.dart';
+
+abstract class A {
+ int get bar;
+ void baz(int x, {String y, double z});
+ void set foo(int value);
+}
+
+class B implements A {
+ noSuchMethod(_) {}
+}
+
+class C extends B {}
+
+class E implements D {}
+
+class F extends E {}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/forwarders_not_assumed_from_mixin.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/forwarders_not_assumed_from_mixin.dart.textual_outline.expect
new file mode 100644
index 0000000..02f378d
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/forwarders_not_assumed_from_mixin.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+abstract class I {
+ void foo();
+}
+
+class A implements I {
+ dynamic noSuchMethod(Invocation i) => null;
+}
+
+class B extends Object with A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/forwarders_not_assumed_from_mixin.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/forwarders_not_assumed_from_mixin.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..02f378d
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/forwarders_not_assumed_from_mixin.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+abstract class I {
+ void foo();
+}
+
+class A implements I {
+ dynamic noSuchMethod(Invocation i) => null;
+}
+
+class B extends Object with A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.textual_outline.expect
new file mode 100644
index 0000000..9c32609
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class A {
+ dynamic noSuchMethod(Invocation i) {}
+}
+
+class I {
+ void foo() {}
+}
+
+class B extends A implements I {}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0318a57
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+class A {
+ dynamic noSuchMethod(Invocation i) {}
+}
+
+class B extends A implements I {}
+
+class I {
+ void foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.textual_outline.expect
new file mode 100644
index 0000000..bbc3c6c
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+class I {
+ dynamic noSuchMethod(Invocation i) => null;
+ void foo();
+}
+
+class M {
+ dynamic noSuchMethod(Invocation i) => null;
+}
+
+class A extends Object with M implements I {}
+
+class B extends Object with M implements I {}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a90747d
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+class A extends Object with M implements I {}
+
+class B extends Object with M implements I {}
+
+class I {
+ dynamic noSuchMethod(Invocation i) => null;
+ void foo();
+}
+
+class M {
+ dynamic noSuchMethod(Invocation i) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/multiple_abstract_setters.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/multiple_abstract_setters.dart.textual_outline.expect
new file mode 100644
index 0000000..af6ee89
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/multiple_abstract_setters.dart.textual_outline.expect
@@ -0,0 +1,20 @@
+class A {
+ void set foo(int value) {}
+ int get bar => null;
+}
+
+class B {
+ void set foo(double value) {}
+ double get bar => null;
+}
+
+class C {
+ void set foo(num value) {}
+ Null get bar => null;
+}
+
+class D implements C, A, B {
+ noSuchMethod(_) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/multiple_abstract_setters.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/multiple_abstract_setters.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..02e07d5
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/multiple_abstract_setters.dart.textual_outline_modelled.expect
@@ -0,0 +1,20 @@
+class A {
+ int get bar => null;
+ void set foo(int value) {}
+}
+
+class B {
+ double get bar => null;
+ void set foo(double value) {}
+}
+
+class C {
+ Null get bar => null;
+ void set foo(num value) {}
+}
+
+class D implements C, A, B {
+ noSuchMethod(_) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes.dart.textual_outline.expect
new file mode 100644
index 0000000..85d405d
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+abstract class A {
+ noSuchMethod(i) => null;
+ void foo();
+}
+
+class B extends A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..85d405d
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+abstract class A {
+ noSuchMethod(i) => null;
+ void foo();
+}
+
+class B extends A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes_chain.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes_chain.dart.textual_outline.expect
new file mode 100644
index 0000000..09d5fc9
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes_chain.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+abstract class A {
+ noSuchMethod(i) => null;
+ void foo();
+}
+
+abstract class B extends A {}
+
+class C extends B {}
+
+class D extends C {}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes_chain.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes_chain.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..09d5fc9
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes_chain.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+abstract class A {
+ noSuchMethod(i) => null;
+ void foo();
+}
+
+abstract class B extends A {}
+
+class C extends B {}
+
+class D extends C {}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.textual_outline.expect
new file mode 100644
index 0000000..7ce56ae
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class M {
+ dynamic noSuchMethod(Invocation invocation) => null;
+}
+
+class A extends M {
+ void call(String s);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0421166
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class A extends M {
+ void call(String s);
+}
+
+class M {
+ dynamic noSuchMethod(Invocation invocation) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.textual_outline.expect
new file mode 100644
index 0000000..eece1da
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class A {
+ dynamic noSuchMethod(Invocation i) {}
+}
+
+class B extends Object with A {
+ void foo();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..eece1da
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class A {
+ dynamic noSuchMethod(Invocation i) {}
+}
+
+class B extends Object with A {
+ void foo();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.textual_outline.expect
new file mode 100644
index 0000000..284127b
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library private;
+
+import './private_module.dart' show Fisk;
+
+abstract class Foo {
+ dynamic noSuchMethod(Invocation invocation) => 42;
+}
+
+class Bar extends Foo implements Fisk {}
+
+class Baz extends Foo implements Fisk {
+ _hest() => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..284127b
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library private;
+
+import './private_module.dart' show Fisk;
+
+abstract class Foo {
+ dynamic noSuchMethod(Invocation invocation) => 42;
+}
+
+class Bar extends Foo implements Fisk {}
+
+class Baz extends Foo implements Fisk {
+ _hest() => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private_module.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/private_module.dart.textual_outline.expect
new file mode 100644
index 0000000..ad5304f
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private_module.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library private_module;
+
+abstract class Fisk {
+ void _hest();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private_module.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/private_module.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ad5304f
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private_module.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library private_module;
+
+abstract class Fisk {
+ void _hest();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.textual_outline.expect
new file mode 100644
index 0000000..cb9b84e
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+abstract class Foo {
+ void _foo();
+}
+
+class Bar extends Foo {
+ dynamic noSuchMethod(Invocation invocation) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cb9b84e
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+abstract class Foo {
+ void _foo();
+}
+
+class Bar extends Foo {
+ dynamic noSuchMethod(Invocation invocation) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/same.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/same.dart.textual_outline.expect
new file mode 100644
index 0000000..7b3ce88
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/same.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class A {
+ dynamic noSuchMethod(Invocation i) {}
+ void foo();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/same.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/same.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7b3ce88
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/same.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class A {
+ dynamic noSuchMethod(Invocation i) {}
+ void foo();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart.textual_outline.expect
new file mode 100644
index 0000000..3ae19c6
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class A {
+ void foo(int x) {}
+ void set foo(int x);
+ dynamic noSuchMethod(Invocation i) => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c1ccdb0f
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class A {
+ dynamic noSuchMethod(Invocation i) => null;
+ void foo(int x) {}
+ void set foo(int x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.textual_outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.textual_outline.expect
new file mode 100644
index 0000000..9ae8a30
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+abstract class I<T> {
+ T foo();
+}
+
+class M {
+ dynamic noSuchMethod(Invocation i) {}
+}
+
+class A extends Object with M implements I<int> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1762a6e
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+abstract class I<T> {
+ T foo();
+}
+
+class A extends Object with M implements I<int> {}
+
+class M {
+ dynamic noSuchMethod(Invocation i) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.strong.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.strong.expect
index 6d57a3c..a62ffbb 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.strong.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.strong.expect
@@ -2,13 +2,13 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:13:42: Error: A value of type 'Null?' can't be assigned to a variable of type 'FutureOr<A>'.
+// pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:13:42: Error: A value of type 'Null' can't be assigned to a variable of type 'FutureOr<A>'.
// - 'FutureOr' is from 'dart:async'.
// - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
// FutureOr<AAlias> foLegacyNonNullable = null; // error
// ^
//
-// pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:15:47: Error: A value of type 'Null?' can't be assigned to a variable of type 'FutureOr<A>'.
+// pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:15:47: Error: A value of type 'Null' can't be assigned to a variable of type 'FutureOr<A>'.
// - 'FutureOr' is from 'dart:async'.
// - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
// FutureOr<AAliasNonNullable> foNonNullable = null; // error
@@ -24,13 +24,13 @@
typedef AAliasNonNullable = opt::A;
typedef AAliasNullable = opt::A?;
static method test() → dynamic {
- asy::FutureOr<opt::A> foLegacyNonNullable = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:13:42: Error: A value of type 'Null?' can't be assigned to a variable of type 'FutureOr<A>'.
+ asy::FutureOr<opt::A> foLegacyNonNullable = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:13:42: Error: A value of type 'Null' can't be assigned to a variable of type 'FutureOr<A>'.
- 'FutureOr' is from 'dart:async'.
- 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
FutureOr<AAlias> foLegacyNonNullable = null; // error
^" in null as{TypeError,ForNonNullableByDefault} asy::FutureOr<opt::A>;
asy::FutureOr<opt::A?> foLegacyNullable = null;
- asy::FutureOr<opt::A> foNonNullable = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:15:47: Error: A value of type 'Null?' can't be assigned to a variable of type 'FutureOr<A>'.
+ asy::FutureOr<opt::A> foNonNullable = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:15:47: Error: A value of type 'Null' can't be assigned to a variable of type 'FutureOr<A>'.
- 'FutureOr' is from 'dart:async'.
- 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
FutureOr<AAliasNonNullable> foNonNullable = null; // error
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.strong.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.strong.transformed.expect
index 6d57a3c..a62ffbb 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.strong.transformed.expect
@@ -2,13 +2,13 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:13:42: Error: A value of type 'Null?' can't be assigned to a variable of type 'FutureOr<A>'.
+// pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:13:42: Error: A value of type 'Null' can't be assigned to a variable of type 'FutureOr<A>'.
// - 'FutureOr' is from 'dart:async'.
// - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
// FutureOr<AAlias> foLegacyNonNullable = null; // error
// ^
//
-// pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:15:47: Error: A value of type 'Null?' can't be assigned to a variable of type 'FutureOr<A>'.
+// pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:15:47: Error: A value of type 'Null' can't be assigned to a variable of type 'FutureOr<A>'.
// - 'FutureOr' is from 'dart:async'.
// - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
// FutureOr<AAliasNonNullable> foNonNullable = null; // error
@@ -24,13 +24,13 @@
typedef AAliasNonNullable = opt::A;
typedef AAliasNullable = opt::A?;
static method test() → dynamic {
- asy::FutureOr<opt::A> foLegacyNonNullable = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:13:42: Error: A value of type 'Null?' can't be assigned to a variable of type 'FutureOr<A>'.
+ asy::FutureOr<opt::A> foLegacyNonNullable = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:13:42: Error: A value of type 'Null' can't be assigned to a variable of type 'FutureOr<A>'.
- 'FutureOr' is from 'dart:async'.
- 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
FutureOr<AAlias> foLegacyNonNullable = null; // error
^" in null as{TypeError,ForNonNullableByDefault} asy::FutureOr<opt::A>;
asy::FutureOr<opt::A?> foLegacyNullable = null;
- asy::FutureOr<opt::A> foNonNullable = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:15:47: Error: A value of type 'Null?' can't be assigned to a variable of type 'FutureOr<A>'.
+ asy::FutureOr<opt::A> foNonNullable = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:15:47: Error: A value of type 'Null' can't be assigned to a variable of type 'FutureOr<A>'.
- 'FutureOr' is from 'dart:async'.
- 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
FutureOr<AAliasNonNullable> foNonNullable = null; // error
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.textual_outline.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.textual_outline.expect
new file mode 100644
index 0000000..8ff38a5
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'dart:async'; import 'issue41501_lib.dart';
+typedef AAliasNonNullable = A;
+typedef AAliasNullable = A?;
+test() { }
+main() { }
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.weak.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.weak.expect
index 6d57a3c..a62ffbb 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.weak.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.weak.expect
@@ -2,13 +2,13 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:13:42: Error: A value of type 'Null?' can't be assigned to a variable of type 'FutureOr<A>'.
+// pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:13:42: Error: A value of type 'Null' can't be assigned to a variable of type 'FutureOr<A>'.
// - 'FutureOr' is from 'dart:async'.
// - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
// FutureOr<AAlias> foLegacyNonNullable = null; // error
// ^
//
-// pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:15:47: Error: A value of type 'Null?' can't be assigned to a variable of type 'FutureOr<A>'.
+// pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:15:47: Error: A value of type 'Null' can't be assigned to a variable of type 'FutureOr<A>'.
// - 'FutureOr' is from 'dart:async'.
// - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
// FutureOr<AAliasNonNullable> foNonNullable = null; // error
@@ -24,13 +24,13 @@
typedef AAliasNonNullable = opt::A;
typedef AAliasNullable = opt::A?;
static method test() → dynamic {
- asy::FutureOr<opt::A> foLegacyNonNullable = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:13:42: Error: A value of type 'Null?' can't be assigned to a variable of type 'FutureOr<A>'.
+ asy::FutureOr<opt::A> foLegacyNonNullable = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:13:42: Error: A value of type 'Null' can't be assigned to a variable of type 'FutureOr<A>'.
- 'FutureOr' is from 'dart:async'.
- 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
FutureOr<AAlias> foLegacyNonNullable = null; // error
^" in null as{TypeError,ForNonNullableByDefault} asy::FutureOr<opt::A>;
asy::FutureOr<opt::A?> foLegacyNullable = null;
- asy::FutureOr<opt::A> foNonNullable = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:15:47: Error: A value of type 'Null?' can't be assigned to a variable of type 'FutureOr<A>'.
+ asy::FutureOr<opt::A> foNonNullable = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:15:47: Error: A value of type 'Null' can't be assigned to a variable of type 'FutureOr<A>'.
- 'FutureOr' is from 'dart:async'.
- 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
FutureOr<AAliasNonNullable> foNonNullable = null; // error
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.weak.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.weak.transformed.expect
index 6d57a3c..a62ffbb 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart.weak.transformed.expect
@@ -2,13 +2,13 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:13:42: Error: A value of type 'Null?' can't be assigned to a variable of type 'FutureOr<A>'.
+// pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:13:42: Error: A value of type 'Null' can't be assigned to a variable of type 'FutureOr<A>'.
// - 'FutureOr' is from 'dart:async'.
// - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
// FutureOr<AAlias> foLegacyNonNullable = null; // error
// ^
//
-// pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:15:47: Error: A value of type 'Null?' can't be assigned to a variable of type 'FutureOr<A>'.
+// pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:15:47: Error: A value of type 'Null' can't be assigned to a variable of type 'FutureOr<A>'.
// - 'FutureOr' is from 'dart:async'.
// - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
// FutureOr<AAliasNonNullable> foNonNullable = null; // error
@@ -24,13 +24,13 @@
typedef AAliasNonNullable = opt::A;
typedef AAliasNullable = opt::A?;
static method test() → dynamic {
- asy::FutureOr<opt::A> foLegacyNonNullable = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:13:42: Error: A value of type 'Null?' can't be assigned to a variable of type 'FutureOr<A>'.
+ asy::FutureOr<opt::A> foLegacyNonNullable = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:13:42: Error: A value of type 'Null' can't be assigned to a variable of type 'FutureOr<A>'.
- 'FutureOr' is from 'dart:async'.
- 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
FutureOr<AAlias> foLegacyNonNullable = null; // error
^" in null as{TypeError,ForNonNullableByDefault} asy::FutureOr<opt::A>;
asy::FutureOr<opt::A?> foLegacyNullable = null;
- asy::FutureOr<opt::A> foNonNullable = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:15:47: Error: A value of type 'Null?' can't be assigned to a variable of type 'FutureOr<A>'.
+ asy::FutureOr<opt::A> foNonNullable = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nonfunction_type_aliases/issue41501.dart:15:47: Error: A value of type 'Null' can't be assigned to a variable of type 'FutureOr<A>'.
- 'FutureOr' is from 'dart:async'.
- 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue41501_lib.dart'.
FutureOr<AAliasNonNullable> foNonNullable = null; // error
diff --git a/pkg/front_end/testcases/rasta/abstract_constructor.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/abstract_constructor.dart.textual_outline.expect
new file mode 100644
index 0000000..101867d
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/abstract_constructor.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+abstract class C {}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/abstract_constructor.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/abstract_constructor.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..101867d
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/abstract_constructor.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+abstract class C {}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/bad_constructor_redirection.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/bad_constructor_redirection.dart.textual_outline.expect
new file mode 100644
index 0000000..8c60ced
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/bad_constructor_redirection.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class C {
+ const C() : this.x(1);
+ const C.x();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/bad_constructor_redirection.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/bad_constructor_redirection.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8c60ced
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/bad_constructor_redirection.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class C {
+ const C() : this.x(1);
+ const C.x();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/bad_continue.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/bad_continue.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/bad_continue.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/bad_continue.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/bad_continue.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/bad_continue.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/bad_default_constructor.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/bad_default_constructor.dart.textual_outline.expect
new file mode 100644
index 0000000..5f62a0e
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/bad_default_constructor.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class A {
+ A(x);
+}
+
+class B extends A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/bad_default_constructor.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/bad_default_constructor.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5f62a0e
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/bad_default_constructor.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class A {
+ A(x);
+}
+
+class B extends A {}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart.textual_outline.expect
new file mode 100644
index 0000000..a9880f1
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class A {
+ A(x);
+}
+
+class B extends A {
+ const B() : super();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a9880f1
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class A {
+ A(x);
+}
+
+class B extends A {
+ const B() : super();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart.textual_outline.expect
new file mode 100644
index 0000000..9f4c8b4
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class A {
+ A(this.x);
+}
+
+class B extends A {
+ const B();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9f4c8b4
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class A {
+ A(this.x);
+}
+
+class B extends A {
+ const B();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/bad_redirection.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/bad_redirection.dart.textual_outline.expect
new file mode 100644
index 0000000..5b6ce13
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/bad_redirection.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class Foo {
+ Foo() = Bar;
+}
+class Bar extends Foo {
+ factory Bar() => null;
+}
+main() { }
diff --git a/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..02d3a33
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class C {
+ C() : field = null;
+ set field(value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..02d3a33
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class C {
+ C() : field = null;
+ set field(value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/bad_unicode.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/bad_unicode.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/bad_unicode.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/bad_unicode.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/bad_unicode.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/bad_unicode.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/breaking_bad.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/breaking_bad.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/breaking_bad.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/breaking_bad.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/breaking_bad.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/breaking_bad.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/cascades.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/cascades.dart.textual_outline.expect
new file mode 100644
index 0000000..014f06c
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/cascades.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class A {
+ add(x) => x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/cascades.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/cascades.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..014f06c
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/cascades.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+class A {
+ add(x) => x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/class_hierarchy.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/class_hierarchy.dart.textual_outline.expect
new file mode 100644
index 0000000..4730157
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/class_hierarchy.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class A extends Missing {}
+
+class B implements Missing {}
+
+class C = Object with Missing;
+
+class D {
+ factory D() = Missing;
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/rasta/class_hierarchy.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/class_hierarchy.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4730157
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/class_hierarchy.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+class A extends Missing {}
+
+class B implements Missing {}
+
+class C = Object with Missing;
+
+class D {
+ factory D() = Missing;
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/rasta/class_member.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/class_member.dart.textual_outline.expect
new file mode 100644
index 0000000..f3931ce
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/class_member.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class Foo {
+ a() {}
+ b() {}
+ c() {}
+ var field1;
+ var field2;
+ var field3;
+ Foo.constructor1();
+ Foo.constructor2();
+ Foo.constructor3();
+}
diff --git a/pkg/front_end/testcases/rasta/class_member.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/class_member.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2b3571b
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/class_member.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+class Foo {
+ Foo.constructor1();
+ Foo.constructor2();
+ Foo.constructor3();
+ a() {}
+ b() {}
+ c() {}
+ var field1;
+ var field2;
+ var field3;
+}
diff --git a/pkg/front_end/testcases/rasta/constant_get_and_invoke.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/constant_get_and_invoke.dart.textual_outline.expect
new file mode 100644
index 0000000..6b59d01
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/constant_get_and_invoke.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+const c = 1;
+main() {}
diff --git a/pkg/front_end/testcases/rasta/constant_get_and_invoke.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/constant_get_and_invoke.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6b59d01
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/constant_get_and_invoke.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+const c = 1;
+main() {}
diff --git a/pkg/front_end/testcases/rasta/deferred_load.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/deferred_load.dart.textual_outline.expect
new file mode 100644
index 0000000..e513d3a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/deferred_load.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/deferred_load.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/deferred_load.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e513d3a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/deferred_load.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/duplicated_mixin.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/duplicated_mixin.dart.textual_outline.expect
new file mode 100644
index 0000000..6da2cea
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/duplicated_mixin.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class Mixin {
+ var field;
+}
+
+class A extends Object with Mixin, Mixin {}
diff --git a/pkg/front_end/testcases/rasta/duplicated_mixin.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/duplicated_mixin.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..525de0e
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/duplicated_mixin.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+class A extends Object with Mixin, Mixin {}
+
+class Mixin {
+ var field;
+}
diff --git a/pkg/front_end/testcases/rasta/enum.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/enum.dart.textual_outline.expect
new file mode 100644
index 0000000..7d25fa5
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/enum.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+enum Foo {
+ ec1,
+ ec2,
+}
+main() {}
diff --git a/pkg/front_end/testcases/rasta/enum.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/enum.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7d25fa5
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/enum.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+enum Foo {
+ ec1,
+ ec2,
+}
+main() {}
diff --git a/pkg/front_end/testcases/rasta/export.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/export.dart.textual_outline.expect
new file mode 100644
index 0000000..a55dbf5
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/export.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library export;
+
+export 'foo.dart';
diff --git a/pkg/front_end/testcases/rasta/export.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/export.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a55dbf5
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/export.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library export;
+
+export 'foo.dart';
diff --git a/pkg/front_end/testcases/rasta/external_factory_redirection.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/external_factory_redirection.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/external_factory_redirection.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/external_factory_redirection.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/external_factory_redirection.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/external_factory_redirection.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/foo.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/foo.dart.textual_outline.expect
new file mode 100644
index 0000000..0d1b8df4
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/foo.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library foo;
+
+foo() {}
diff --git a/pkg/front_end/testcases/rasta/foo.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/foo.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0d1b8df4
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/foo.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library foo;
+
+foo() {}
diff --git a/pkg/front_end/testcases/rasta/for_loop.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/for_loop.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/for_loop.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/for_loop.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/for_loop.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/for_loop.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/generic_factory.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/generic_factory.dart.textual_outline.expect
new file mode 100644
index 0000000..0b8bde5
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/generic_factory.dart.textual_outline.expect
@@ -0,0 +1,24 @@
+class C1 {}
+
+class C2 {}
+
+class C3 {}
+
+class A<T> {
+ A.internal();
+ factory A.a() = B<T>.a;
+ factory A.b() = B<C1>.a;
+ factory A.c() = Missing;
+}
+
+class B<S> extends A<S> {
+ B.internal() : super.internal();
+ factory B.a() = C<S>;
+ factory B.b() = C<C2>;
+}
+
+class C<U> extends B<U> {
+ C() : super.internal();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/generic_factory.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/generic_factory.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0bec190
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/generic_factory.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+class A<T> {
+ A.internal();
+ factory A.a() = B<T>.a;
+ factory A.b() = B<C1>.a;
+ factory A.c() = Missing;
+}
+
+class B<S> extends A<S> {
+ B.internal() : super.internal();
+ factory B.a() = C<S>;
+ factory B.b() = C<C2>;
+}
+
+class C1 {}
+
+class C2 {}
+
+class C3 {}
+
+class C<U> extends B<U> {
+ C() : super.internal();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/hello.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/hello.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/hello.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/hello.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/hello.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/hello.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/import_export.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/import_export.dart.textual_outline.expect
new file mode 100644
index 0000000..9b23e8d
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/import_export.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+import 'export.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/import_export.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/import_export.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9b23e8d
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/import_export.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+import 'export.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000001.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000001.dart.textual_outline.expect
new file mode 100644
index 0000000..e580ef6
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000001.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+test0(x) {}
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000001.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000001.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..246dbef
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000001.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+main() {}
+test0(x) {}
diff --git a/pkg/front_end/testcases/rasta/issue_000002.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000002.dart.textual_outline.expect
new file mode 100644
index 0000000..e7403ac
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000002.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+import 'dart:typed_data';
+import 'package:expect/expect.dart';
+
+var list = [1, 2, 3];
+
+class Foo {
+ final value;
+ Foo(this.value) {}
+ factory Foo.fac(value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000002.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000002.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e19be7a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000002.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+import 'dart:typed_data';
+import 'package:expect/expect.dart';
+
+class Foo {
+ Foo(this.value) {}
+ factory Foo.fac(value) {}
+ final value;
+}
+
+main() {}
+var list = [1, 2, 3];
diff --git a/pkg/front_end/testcases/rasta/issue_000004.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000004.dart.textual_outline.expect
new file mode 100644
index 0000000..ffd82da
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000004.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+import 'package:expect/expect.dart';
+
+fact4() {}
+fact5() {}
+var global;
+fact6() {}
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000004.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000004.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..68c6364
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000004.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+import 'package:expect/expect.dart';
+
+fact4() {}
+fact5() {}
+fact6() {}
+main() {}
+var global;
diff --git a/pkg/front_end/testcases/rasta/issue_000006.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000006.dart.textual_outline.expect
new file mode 100644
index 0000000..c9b955f
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000006.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+var list = [1, 2, 3];
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000006.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000006.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ef8eed0
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000006.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+main() {}
+var list = [1, 2, 3];
diff --git a/pkg/front_end/testcases/rasta/issue_000007.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000007.dart.textual_outline.expect
new file mode 100644
index 0000000..58c40fa
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000007.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class Base {}
+
+class Mixin {
+ foo() => print('foo');
+}
+
+class Sub extends Base with Mixin {}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000007.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000007.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..58c40fa
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000007.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class Base {}
+
+class Mixin {
+ foo() => print('foo');
+}
+
+class Sub extends Base with Mixin {}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000008.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000008.dart.textual_outline.expect
new file mode 100644
index 0000000..7c1de3a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000008.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class C {
+ final x;
+ C(this.x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000008.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000008.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2a92244
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000008.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class C {
+ C(this.x);
+ final x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000011.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000011.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000011.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000011.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000011.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000011.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000012.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000012.dart.textual_outline.expect
new file mode 100644
index 0000000..fe1927c
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000012.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class A {
+ var field;
+}
+
+class B extends A {
+ m() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000012.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000012.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fe1927c
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000012.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class A {
+ var field;
+}
+
+class B extends A {
+ m() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000025.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000025.dart.textual_outline.expect
new file mode 100644
index 0000000..b31966b
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000025.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+get x => 42;
+set x(val) {}
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000025.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000025.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..58187fc
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000025.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+get x => 42;
+main() {}
+set x(val) {}
diff --git a/pkg/front_end/testcases/rasta/issue_000026.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000026.dart.textual_outline.expect
new file mode 100644
index 0000000..3c6152d
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000026.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+class C {
+ var a;
+ var b = 0;
+ var c = 1 + 2;
+}
+
+class D {
+ var a;
+ var b = 1;
+ var c = 2 - 3;
+ D();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000026.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000026.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ae0f47e
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000026.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+class C {
+ var a;
+ var b = 0;
+ var c = 1 + 2;
+}
+
+class D {
+ D();
+ var a;
+ var b = 1;
+ var c = 2 - 3;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000031.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000031.dart.textual_outline.expect
new file mode 100644
index 0000000..1123642
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000031.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+import 'dart:math' as math;
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000031.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000031.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1123642
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000031.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+import 'dart:math' as math;
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000032.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000032.dart.textual_outline.expect
new file mode 100644
index 0000000..6a6d39c
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000032.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class C {
+ C< >( ){ }
+}
+main() { }
diff --git a/pkg/front_end/testcases/rasta/issue_000033.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000033.dart.textual_outline.expect
new file mode 100644
index 0000000..c4716a7
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000033.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+@JS()
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000033.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000033.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c4716a7
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000033.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+@JS()
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000034.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000034.dart.textual_outline.expect
new file mode 100644
index 0000000..a682f2e
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000034.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class C {
+ const C() : =this.x;
+}
+main() { }
diff --git a/pkg/front_end/testcases/rasta/issue_000036.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000036.dart.textual_outline.expect
new file mode 100644
index 0000000..603c715
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000036.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() => a. - 5;
diff --git a/pkg/front_end/testcases/rasta/issue_000039.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000039.dart.textual_outline.expect
new file mode 100644
index 0000000..823e1c7
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000039.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class A {
+ var a;
+ A(x) {}
+}
+
+class B extends A {}
diff --git a/pkg/front_end/testcases/rasta/issue_000039.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000039.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ab5d564
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000039.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class A {
+ A(x) {}
+ var a;
+}
+
+class B extends A {}
diff --git a/pkg/front_end/testcases/rasta/issue_000041.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000041.dart.textual_outline.expect
new file mode 100644
index 0000000..0690e46
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000041.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class C {
+ test() {}
+}
+
+use(_) => null;
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000041.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000041.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..57013ed
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000041.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class C {
+ test() {}
+}
+
+main() {}
+use(_) => null;
diff --git a/pkg/front_end/testcases/rasta/issue_000042.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000042.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000042.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000042.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000042.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000042.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000043.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000043.dart.textual_outline.expect
new file mode 100644
index 0000000..6bc9bc7
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000043.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+class C {
+ get x => '$C'.hashCode;
+}
diff --git a/pkg/front_end/testcases/rasta/issue_000043.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000043.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6bc9bc7
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000043.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+class C {
+ get x => '$C'.hashCode;
+}
diff --git a/pkg/front_end/testcases/rasta/issue_000044.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000044.dart.textual_outline.expect
new file mode 100644
index 0000000..934729b
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000044.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+a b(c) = d;
+class C {
+ const C.constant();
+ C.missingFactoryKeyword() = C.constant;
+ const factory C.good() = C.constant;
+ C notEvenAConstructor(a) = h;
+}
+main() { }
diff --git a/pkg/front_end/testcases/rasta/issue_000046.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000046.dart.textual_outline.expect
new file mode 100644
index 0000000..0b29b47
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000046.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class C {
+ C c = new Object();
+ )
+ ();
+}
diff --git a/pkg/front_end/testcases/rasta/issue_000047.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000047.dart.textual_outline.expect
new file mode 100644
index 0000000..0967161
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000047.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+typedef void T(C<C>);
+T main() => null;
diff --git a/pkg/front_end/testcases/rasta/issue_000048.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000048.dart.textual_outline.expect
new file mode 100644
index 0000000..75793bc
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000048.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+class A {
+ bool v1;
+ num v2;
+ A(bool this.v1, num this.v2);
+}
+
+class M1 {
+ num v2 = 0;
+}
+
+class C = A with M1;
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000048.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000048.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4d8b868
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000048.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+class A {
+ A(bool this.v1, num this.v2);
+ bool v1;
+ num v2;
+}
+
+class M1 {
+ num v2 = 0;
+}
+
+class C = A with M1;
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000052.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000052.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000052.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000052.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000052.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000052.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000053.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000053.dart.textual_outline.expect
new file mode 100644
index 0000000..aa3a004
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000053.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class C {
+ operator ==(other) => throw 'x';
+ test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000053.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000053.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..aa3a004
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000053.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class C {
+ operator ==(other) => throw 'x';
+ test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000067.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000067.dart.textual_outline.expect
new file mode 100644
index 0000000..a569cc4
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000067.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+import "package:expect/expect.dart";
+
+class A {
+ A() {}
+ factory A.foo() = C.bar;
+ int m() {}
+}
+
+class C extends A {
+ C() {}
+ factory C.bar() = D;
+ int m() {}
+}
+
+class D extends C {
+ int m() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000067.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000067.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a569cc4
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000067.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+import "package:expect/expect.dart";
+
+class A {
+ A() {}
+ factory A.foo() = C.bar;
+ int m() {}
+}
+
+class C extends A {
+ C() {}
+ factory C.bar() = D;
+ int m() {}
+}
+
+class D extends C {
+ int m() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000068.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000068.dart.textual_outline.expect
new file mode 100644
index 0000000..cde3517
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000068.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+import "package:expect/expect.dart";
+
+class G<T> {}
+
+class A {}
+
+class B extends A {}
+
+class C extends B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000068.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000068.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..dd18446
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000068.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+import "package:expect/expect.dart";
+
+class A {}
+
+class B extends A {}
+
+class C extends B {}
+
+class G<T> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000069.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000069.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000069.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000069.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000069.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000069.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000070.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000070.dart.textual_outline.expect
new file mode 100644
index 0000000..18be5ac
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000070.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+import "package:expect/expect.dart";
+
+class A<N, S, U> {
+ final List<U> field;
+ A(N n, S s) : field = new List<U>() {}
+ A.empty() : field = null {}
+ factory A.f(S s) {}
+ const A.c(U u, S s) : field = const [null];
+ List<U> get getter {}
+ void set setter(S s) {}
+}
+
+abstract class J<Aa, B> {}
+
+abstract class I<H, C, K> extends J<C, K> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000070.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000070.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cefd17f
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000070.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+import "package:expect/expect.dart";
+
+abstract class I<H, C, K> extends J<C, K> {}
+
+abstract class J<Aa, B> {}
+
+class A<N, S, U> {
+ A(N n, S s) : field = new List<U>() {}
+ A.empty() : field = null {}
+ List<U> get getter {}
+ const A.c(U u, S s) : field = const [null];
+ factory A.f(S s) {}
+ final List<U> field;
+ void set setter(S s) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000080.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000080.dart.textual_outline.expect
new file mode 100644
index 0000000..e1dd6e2
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000080.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class Mixin {
+ var field;
+ foo() => 87;
+}
+
+class Foo extends Object with Mixin {
+ foo() => super.foo();
+ bar() => super.field;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000080.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000080.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8ed966c
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000080.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+class Foo extends Object with Mixin {
+ bar() => super.field;
+ foo() => super.foo();
+}
+
+class Mixin {
+ foo() => 87;
+ var field;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000081.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/issue_000081.dart.textual_outline.expect
new file mode 100644
index 0000000..e1cbad9
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000081.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+class Base {
+ int hashCode = 42;
+}
+
+class Sub extends Base {
+ int _hashCode = null;
+ get hashCode => _hashCode ??= super.hashCode;
+ foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/issue_000081.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/issue_000081.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0170932
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000081.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+class Base {
+ int hashCode = 42;
+}
+
+class Sub extends Base {
+ foo() {}
+ get hashCode => _hashCode ??= super.hashCode;
+ int _hashCode = null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/malformed_const_constructor.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/malformed_const_constructor.dart.textual_outline.expect
new file mode 100644
index 0000000..c0d76bf
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/malformed_const_constructor.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class A {
+ const A() : x = 'foo' { }
+ :
+ x = 'foo' ;
+}
+main() { }
diff --git a/pkg/front_end/testcases/rasta/malformed_function.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/malformed_function.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/malformed_function.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/malformed_function.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/malformed_function.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/malformed_function.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/malformed_function_type.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/malformed_function_type.dart.textual_outline.expect
new file mode 100644
index 0000000..6587e81
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/malformed_function_type.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+typedef Handle Handle(String command);
+main() {}
diff --git a/pkg/front_end/testcases/rasta/malformed_function_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/malformed_function_type.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2afa7c6
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/malformed_function_type.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+main() {}
+typedef Handle Handle(String command);
diff --git a/pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..881328b
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart.textual_outline.expect
@@ -0,0 +1 @@
+main(arguments = [x]) { }
diff --git a/pkg/front_end/testcases/rasta/mixin_library.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/mixin_library.dart.textual_outline.expect
new file mode 100644
index 0000000..6d98bf9
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/mixin_library.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+library test.mixin_library;
+
+f() => 2;
+V() => 87;
+_private() => 117;
+
+class Mixin<T> {
+ var x = f(), y, z;
+ T t;
+ foo() => super.foo() + f();
+ T g(T a) => null;
+ h() => V();
+ l() => _private();
+ _privateMethod() => 49;
+ publicMethod() => _privateMethod();
+}
+
+foo(m) => m._privateMethod();
diff --git a/pkg/front_end/testcases/rasta/mixin_library.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/mixin_library.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..37481e9
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/mixin_library.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+library test.mixin_library;
+
+V() => 87;
+_private() => 117;
+
+class Mixin<T> {
+ T g(T a) => null;
+ T t;
+ _privateMethod() => 49;
+ foo() => super.foo() + f();
+ h() => V();
+ l() => _private();
+ publicMethod() => _privateMethod();
+ var x = f(), y, z;
+}
+
+f() => 2;
+foo(m) => m._privateMethod();
diff --git a/pkg/front_end/testcases/rasta/native_is_illegal.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/native_is_illegal.dart.textual_outline.expect
new file mode 100644
index 0000000..f28a475
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/native_is_illegal.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+foo() native "foo";
+
+class Bar {
+ Bar get x native "Bar_get_x";
+ set x(Bar value) native "Bar_set_x";
+ f() native "Bar_f";
+ factory Bar() native "Bar_constructor";
+}
diff --git a/pkg/front_end/testcases/rasta/native_is_illegal.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/native_is_illegal.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..61833c6
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/native_is_illegal.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+class Bar {
+ Bar get x native "Bar_get_x";
+ f() native "Bar_f";
+ factory Bar() native "Bar_constructor";
+ set x(Bar value) native "Bar_set_x";
+}
+
+foo() native "foo";
diff --git a/pkg/front_end/testcases/rasta/parser_error.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/parser_error.dart.textual_outline.expect
new file mode 100644
index 0000000..bbfef96
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/parser_error.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import "package:expect/expect.dart";
+
+int test(a, {b, c}) {}
+main() {}
diff --git a/pkg/front_end/testcases/rasta/parser_error.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/parser_error.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bbfef96
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/parser_error.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import "package:expect/expect.dart";
+
+int test(a, {b, c}) {}
+main() {}
diff --git a/pkg/front_end/testcases/rasta/previsit_deferred.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/previsit_deferred.dart.textual_outline.expect
new file mode 100644
index 0000000..05d29b6
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/previsit_deferred.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/rasta/previsit_deferred.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/previsit_deferred.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..05d29b6
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/previsit_deferred.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/rasta/static.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/static.dart.textual_outline.expect
new file mode 100644
index 0000000..e24cfe0
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/static.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class Foo {
+ static const staticConstant = 42;
+ static var staticField = 42;
+ static staticFunction() {}
+ static get staticGetter => null;
+ static set staticSetter(_) {}
+}
+
+use(x) {}
+main() {}
diff --git a/pkg/front_end/testcases/rasta/static.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/static.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..079b3cc
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/static.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+class Foo {
+ static const staticConstant = 42;
+ static get staticGetter => null;
+ static set staticSetter(_) {}
+ static staticFunction() {}
+ static var staticField = 42;
+}
+
+main() {}
+use(x) {}
diff --git a/pkg/front_end/testcases/rasta/super.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/super.dart.textual_outline.expect
new file mode 100644
index 0000000..df2c783
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/super.dart.textual_outline.expect
@@ -0,0 +1,34 @@
+class A {
+ var a;
+ var b;
+ var c;
+ var d;
+ get e => null;
+ final f;
+ set g(_) {}
+ get h => null;
+ set h(_) {}
+ get i => null;
+ operator [](_) => null;
+ operator []=(a, b) {}
+ operator ~() => 117;
+ operator -() => 117;
+ operator ==(other) => true;
+ void m() {}
+ void n() {}
+ set n(_) {}
+}
+
+class B extends A {
+ get b => null;
+ set c(x) {}
+ final d;
+ set i(x) {}
+}
+
+class C extends B {
+ test() {}
+}
+
+use(x) {}
+main() {}
diff --git a/pkg/front_end/testcases/rasta/super.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/super.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9ce4369
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/super.dart.textual_outline_modelled.expect
@@ -0,0 +1,34 @@
+class A {
+ final f;
+ get e => null;
+ get h => null;
+ get i => null;
+ operator -() => 117;
+ operator ==(other) => true;
+ operator [](_) => null;
+ operator []=(a, b) {}
+ operator ~() => 117;
+ set g(_) {}
+ set h(_) {}
+ set n(_) {}
+ var a;
+ var b;
+ var c;
+ var d;
+ void m() {}
+ void n() {}
+}
+
+class B extends A {
+ final d;
+ get b => null;
+ set c(x) {}
+ set i(x) {}
+}
+
+class C extends B {
+ test() {}
+}
+
+main() {}
+use(x) {}
diff --git a/pkg/front_end/testcases/rasta/super_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/super_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..c058c68
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/super_initializer.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+class Super {
+ Super.arg0();
+ Super.arg1(a);
+ Super.arg2(a, b);
+}
+
+class Sub extends Super {
+ var field;
+ Sub.arg0()
+ : super.arg0(),
+ field = 42;
+ Sub.arg1(a)
+ : super.arg1(a),
+ field = 42;
+ Sub.arg2(a, b)
+ : super.arg2(a, b),
+ field = 42;
+}
diff --git a/pkg/front_end/testcases/rasta/super_initializer.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/super_initializer.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..65f2d20
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/super_initializer.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+class Sub extends Super {
+ Sub.arg0()
+ : super.arg0(),
+ field = 42;
+ Sub.arg1(a)
+ : super.arg1(a),
+ field = 42;
+ Sub.arg2(a, b)
+ : super.arg2(a, b),
+ field = 42;
+ var field;
+}
+
+class Super {
+ Super.arg0();
+ Super.arg1(a);
+ Super.arg2(a, b);
+}
diff --git a/pkg/front_end/testcases/rasta/super_mixin.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/super_mixin.dart.textual_outline.expect
new file mode 100644
index 0000000..73b67ed
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/super_mixin.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+import "mixin_library.dart" show Mixin;
+
+class Super<S> {
+ foo() => 40;
+ f() => 3;
+}
+
+class C<V> extends Super<V> with Mixin<V> {}
+
+class D extends Super with Mixin {}
+
+class C2<V> = Super<V> with Mixin<V>;
+class D2 = Super with Mixin;
+main() {}
diff --git a/pkg/front_end/testcases/rasta/super_mixin.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/super_mixin.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7fb14f0
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/super_mixin.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+import "mixin_library.dart" show Mixin;
+
+class C<V> extends Super<V> with Mixin<V> {}
+
+class D extends Super with Mixin {}
+
+class Super<S> {
+ f() => 3;
+ foo() => 40;
+}
+
+class C2<V> = Super<V> with Mixin<V>;
+class D2 = Super with Mixin;
+main() {}
diff --git a/pkg/front_end/testcases/rasta/super_operator.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/super_operator.dart.textual_outline.expect
new file mode 100644
index 0000000..0a07631
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/super_operator.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+class A {
+ operator +(String s) => null;
+ operator [](i) => null;
+ operator []=(i, val) {}
+}
+
+class B extends A {
+ operator +(String s) => super + ("${s}${s}");
+ operator [](i) => super[i];
+ operator []=(i, val) => super[i++] += val;
+}
+
+class Autobianchi {
+ g() => super[0];
+}
diff --git a/pkg/front_end/testcases/rasta/super_operator.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/super_operator.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4ecde10
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/super_operator.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+class A {
+ operator +(String s) => null;
+ operator [](i) => null;
+ operator []=(i, val) {}
+}
+
+class Autobianchi {
+ g() => super[0];
+}
+
+class B extends A {
+ operator +(String s) => super + ("${s}${s}");
+ operator [](i) => super[i];
+ operator []=(i, val) => super[i++] += val;
+}
diff --git a/pkg/front_end/testcases/rasta/supports_reflection.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/supports_reflection.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/supports_reflection.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/supports_reflection.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/supports_reflection.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/supports_reflection.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/switch_execution_case_t02.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/switch_execution_case_t02.dart.textual_outline.expect
new file mode 100644
index 0000000..9157edc
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/switch_execution_case_t02.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+test(value) {}
+testEmptyCases(value) {}
+main() {}
diff --git a/pkg/front_end/testcases/rasta/switch_execution_case_t02.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/switch_execution_case_t02.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d7ab5d3
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/switch_execution_case_t02.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+main() {}
+test(value) {}
+testEmptyCases(value) {}
diff --git a/pkg/front_end/testcases/rasta/switch_fall_through.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/switch_fall_through.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/switch_fall_through.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/switch_fall_through.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/switch_fall_through.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/switch_fall_through.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/this_invoke.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/this_invoke.dart.textual_outline.expect
new file mode 100644
index 0000000..ab53b16
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/this_invoke.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class C {
+ m(x) => this(x);
+ call(x) => 42;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/this_invoke.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/this_invoke.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cabde6d
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/this_invoke.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class C {
+ call(x) => 42;
+ m(x) => this(x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/try_label.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/try_label.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/try_label.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/try_label.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/try_label.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/try_label.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/type_literals.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/type_literals.dart.textual_outline.expect
new file mode 100644
index 0000000..3e0fb14
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/type_literals.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+typedef void Func();
+
+class C<T> {
+ test() {}
+}
+
+use(x) {}
+main() {}
diff --git a/pkg/front_end/testcases/rasta/type_literals.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/type_literals.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e51e370
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/type_literals.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class C<T> {
+ test() {}
+}
+
+main() {}
+typedef void Func();
+use(x) {}
diff --git a/pkg/front_end/testcases/rasta/type_with_parse_error.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/type_with_parse_error.dart.textual_outline.expect
new file mode 100644
index 0000000..10499e7
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/type_with_parse_error.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+main() {}
+
+class A {
+ foo() {}
+}
+
+class B<T> {
+ int i;
+}
diff --git a/pkg/front_end/testcases/rasta/type_with_parse_error.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/type_with_parse_error.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a2249be
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/type_with_parse_error.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class A {
+ foo() {}
+}
+
+class B<T> {
+ int i;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/typedef.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/typedef.dart.textual_outline.expect
new file mode 100644
index 0000000..3c109123
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/typedef.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+typedef void Foo();
+main() {}
diff --git a/pkg/front_end/testcases/rasta/typedef.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/typedef.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7f7ac99
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/typedef.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+main() {}
+typedef void Foo();
diff --git a/pkg/front_end/testcases/rasta/unresolved.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/unresolved.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/unresolved.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/unresolved.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/unresolved.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/unresolved.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/rasta/unresolved_constructor.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/unresolved_constructor.dart.textual_outline.expect
new file mode 100644
index 0000000..36e85d2
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/unresolved_constructor.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class Foo {
+ Foo(x, y);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/unresolved_constructor.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/unresolved_constructor.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..36e85d2
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/unresolved_constructor.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+class Foo {
+ Foo(x, y);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/unresolved_for_in.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.textual_outline.expect
new file mode 100644
index 0000000..2b61e89
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+import 'dart:collection' as collection;
+
+typedef void VoidFunction();
+
+class Fisk {
+ it1(x) {}
+}
+
+main(arguments) {}
diff --git a/pkg/front_end/testcases/rasta/unresolved_for_in.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4d7cff8
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+import 'dart:collection' as collection;
+
+class Fisk {
+ it1(x) {}
+}
+
+main(arguments) {}
+typedef void VoidFunction();
diff --git a/pkg/front_end/testcases/rasta/unresolved_recovery.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/unresolved_recovery.dart.textual_outline.expect
new file mode 100644
index 0000000..b529ebe
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/unresolved_recovery.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class E {
+ foo() {}
+}
+
+beforeTestMissingTry() {}
+testMissingTry() {}
+main() {}
diff --git a/pkg/front_end/testcases/rasta/unresolved_recovery.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/unresolved_recovery.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..97cd820
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/unresolved_recovery.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+beforeTestMissingTry() {}
+
+class E {
+ foo() {}
+}
+
+main() {}
+testMissingTry() {}
diff --git a/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.textual_outline.expect b/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.textual_outline.expect
new file mode 100644
index 0000000..afaa1af
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'dart:html';
+import 'dart:io';
+
+main() {}
diff --git a/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..afaa1af
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'dart:html';
+import 'dart:io';
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29937.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_29937.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29937.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29937.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_29937.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29937.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29940.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_29940.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29940.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29940.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_29940.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29940.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29941.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_29941.dart.textual_outline.expect
new file mode 100644
index 0000000..59cd59e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29941.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+bad() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29941.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_29941.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..59cd59e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29941.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+bad() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29942.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_29942.dart.textual_outline.expect
new file mode 100644
index 0000000..a63e3c7
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29942.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+main() { }
+f() = h() => null;
diff --git a/pkg/front_end/testcases/regress/issue_29943.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_29943.dart.textual_outline.expect
new file mode 100644
index 0000000..59cd59e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29943.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+bad() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29943.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_29943.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..59cd59e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29943.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+bad() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29944.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_29944.dart.textual_outline.expect
new file mode 100644
index 0000000..e66ce0f
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29944.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class C {
+ C();
+ var C;
+}
+main() { }
diff --git a/pkg/front_end/testcases/regress/issue_29945.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_29945.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29945.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29945.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_29945.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29945.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29975.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_29975.dart.textual_outline.expect
new file mode 100644
index 0000000..e3e4824
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29975.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+typedef void F();
+typedef void F();
+void main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29975.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_29975.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e3e4824
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29975.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+typedef void F();
+typedef void F();
+void main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29977.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_29977.dart.textual_outline.expect
new file mode 100644
index 0000000..86b4d9e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29977.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+import 'data:async';
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29977.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_29977.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..86b4d9e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29977.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+import 'data:async';
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29978.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_29978.dart.textual_outline.expect
new file mode 100644
index 0000000..2a44271
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29978.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+foo(a, b) => null;
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29978.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_29978.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2a44271
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29978.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+foo(a, b) => null;
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29979.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_29979.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29979.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29979.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_29979.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29979.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29980.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_29980.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29980.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29980.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_29980.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29980.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29981.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_29981.dart.textual_outline.expect
new file mode 100644
index 0000000..2dd5595
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29981.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class C<T> {
+ C<String, String> field;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29981.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_29981.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2dd5595
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29981.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+class C<T> {
+ C<String, String> field;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29983.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_29983.dart.textual_outline.expect
new file mode 100644
index 0000000..1f126e59
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29983.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+f() sync* { }
+g() sync* => dummy;
+h() sync* { }
+main() { }
diff --git a/pkg/front_end/testcases/regress/issue_29984.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_29984.dart.textual_outline.expect
new file mode 100644
index 0000000..59cd59e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29984.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+bad() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29984.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_29984.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..59cd59e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29984.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+bad() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29986.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_29986.dart.textual_outline.expect
new file mode 100644
index 0000000..87a6bb5
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29986.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+main() { }
+C(this.name);
diff --git a/pkg/front_end/testcases/regress/issue_29987.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_29987.dart.textual_outline.expect
new file mode 100644
index 0000000..b891f0b
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29987.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+import "dart_:core";
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_29987.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_29987.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b891f0b
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29987.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+import "dart_:core";
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_30834.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_30834.dart.textual_outline.expect
new file mode 100644
index 0000000..ed95a52
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_30834.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class A {
+ set A(v) { }
+}
+main() { }
diff --git a/pkg/front_end/testcases/regress/issue_30836.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_30836.dart.textual_outline.expect
new file mode 100644
index 0000000..5a96f26
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_30836.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class A {
+ final int x;
+ A() {}
+}
diff --git a/pkg/front_end/testcases/regress/issue_30836.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_30836.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..32f0ddd
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_30836.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+class A {
+ A() {}
+ final int x;
+}
diff --git a/pkg/front_end/testcases/regress/issue_30838.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_30838.dart.textual_outline.expect
new file mode 100644
index 0000000..5ba2d20
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_30838.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+typedef Foo<S> = S Function<T>(T x);
+int foo<T>(T x) => 3;
+Foo<int> bar() => foo;
+void test1() {}
+
+class A {
+ Foo<int> f;
+ void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_30838.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_30838.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..14b3da3
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_30838.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+Foo<int> bar() => foo;
+
+class A {
+ Foo<int> f;
+ void test() {}
+}
+
+int foo<T>(T x) => 3;
+main() {}
+typedef Foo<S> = S Function<T>(T x);
+void test1() {}
diff --git a/pkg/front_end/testcases/regress/issue_30981.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_30981.dart.textual_outline.expect
new file mode 100644
index 0000000..9a413c6
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_30981.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class A {
+ get A { }
+}
+main() { }
diff --git a/pkg/front_end/testcases/regress/issue_30994.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_30994.dart.textual_outline.expect
new file mode 100644
index 0000000..10992017
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_30994.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+library lib; part '$foo'; part '$foo/bar'; part '$for/bar'; part '${true}'; part 'the${1}thing'; part 'part_$foo${'a'}.dart'; part 'part_${'a'}_$foo.dart';
+main() { }
diff --git a/pkg/front_end/testcases/regress/issue_31155.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_31155.dart.textual_outline.expect
new file mode 100644
index 0000000..187e259
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31155.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class A {
+}
+class B {
+}
+class C {
+ var f = Map<A, B;
+ operator> (){ }
+ ;
+}
+void main() { }
diff --git a/pkg/front_end/testcases/regress/issue_31157.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_31157.dart.textual_outline.expect
new file mode 100644
index 0000000..59cd59e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31157.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+bad() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31157.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_31157.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..59cd59e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31157.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+bad() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31171.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_31171.dart.textual_outline.expect
new file mode 100644
index 0000000..945c614
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31171.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+main() { }
+typedef T = ;
+typedef F = Map<String, dynamic> Function();
diff --git a/pkg/front_end/testcases/regress/issue_31180.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_31180.dart.textual_outline.expect
new file mode 100644
index 0000000..59cd59e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31180.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+bad() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31180.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_31180.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..59cd59e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31180.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+bad() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31181.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_31181.dart.textual_outline.expect
new file mode 100644
index 0000000..5b23e22
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31181.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+typedef Foo<T> = T Function<T>(T a);
+Foo x;
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31181.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_31181.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..954749e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31181.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+Foo x;
+main() {}
+typedef Foo<T> = T Function<T>(T a);
diff --git a/pkg/front_end/testcases/regress/issue_31183.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_31183.dart.textual_outline.expect
new file mode 100644
index 0000000..2017348
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31183.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class C {
+ operator unary- ()=> 0;
+}
+main() { }
diff --git a/pkg/front_end/testcases/regress/issue_31184.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_31184.dart.textual_outline.expect
new file mode 100644
index 0000000..59cd59e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31184.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+bad() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31184.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_31184.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..59cd59e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31184.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+bad() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31185.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_31185.dart.textual_outline.expect
new file mode 100644
index 0000000..4a2b0ae
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31185.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+int i = 5;
+int test1() {}
+int test2() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31185.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_31185.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4a2b0ae
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31185.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+int i = 5;
+int test1() {}
+int test2() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31186.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_31186.dart.textual_outline.expect
new file mode 100644
index 0000000..59cd59e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31186.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+bad() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31186.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_31186.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..59cd59e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31186.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+bad() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31187.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_31187.dart.textual_outline.expect
new file mode 100644
index 0000000..59cd59e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31187.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+bad() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31187.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_31187.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..59cd59e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31187.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+bad() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31188.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_31188.dart.textual_outline.expect
new file mode 100644
index 0000000..1ecda27
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31188.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+main() { }
+type T = Map<A, B;
+>
diff --git a/pkg/front_end/testcases/regress/issue_31190.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_31190.dart.textual_outline.expect
new file mode 100644
index 0000000..52c03bd
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31190.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class Typed<T> {
+ T<U> v;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31190.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_31190.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..52c03bd
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31190.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+class Typed<T> {
+ T<U> v;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31192.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_31192.dart.textual_outline.expect
new file mode 100644
index 0000000..2fdc0b7
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31192.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class Increment {
+ int x;
+ Increment() : =x++ { }
+}
+main() { }
diff --git a/pkg/front_end/testcases/regress/issue_31198.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_31198.dart.textual_outline.expect
new file mode 100644
index 0000000..39bb035
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31198.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+abstract class A {
+}
+class B extends A {
+ B(): super().foo() { }
+}
+bad() { }
+main() { }
diff --git a/pkg/front_end/testcases/regress/issue_31213.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_31213.dart.textual_outline.expect
new file mode 100644
index 0000000..87e854f
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31213.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+typedef C<A, K> = int Function<B>(A x, K y, B v);
+typedef D<K> = C<A, K> Function<A>(int z);
+dynamic producer<K>() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31213.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_31213.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..480f6f2
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31213.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+dynamic producer<K>() {}
+main() {}
+typedef C<A, K> = int Function<B>(A x, K y, B v);
+typedef D<K> = C<A, K> Function<A>(int z);
diff --git a/pkg/front_end/testcases/regress/issue_31299.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_31299.dart.textual_outline.expect
new file mode 100644
index 0000000..0298c3a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31299.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class A {
+ int m;
+ A() : m = 1;
+ A.foo() : m = 2;
+ int foo(int a, int b) => a + b * m;
+}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31299.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_31299.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d2c8de1
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31299.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class A {
+ A() : m = 1;
+ A.foo() : m = 2;
+ int foo(int a, int b) => a + b * m;
+ int m;
+}
+
+main() {}
+test() {}
diff --git a/pkg/front_end/testcases/regress/issue_31766.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_31766.dart.textual_outline.expect
new file mode 100644
index 0000000..27434f1
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31766.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class A {
+ foo() => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31766.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_31766.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..27434f1
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31766.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+class A {
+ foo() => null;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31846.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_31846.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31846.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31846.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_31846.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31846.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31996.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_31996.dart.textual_outline.expect
new file mode 100644
index 0000000..7ebf1bc
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31996.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+abstract class B<T> {}
+
+abstract class C<T> {}
+
+class Base implements B {}
+
+class Child1 extends Base implements C<int> {}
+
+class Child2 extends Base implements C<double> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31996.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_31996.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7ebf1bc
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31996.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+abstract class B<T> {}
+
+abstract class C<T> {}
+
+class Base implements B {}
+
+class Child1 extends Base implements C<int> {}
+
+class Child2 extends Base implements C<double> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_32182.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_32182.dart.textual_outline.expect
new file mode 100644
index 0000000..22f0c87
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_32182.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+import "issue_32182.dart" as self;
+
+class A<T> {}
+
+class M {
+ m() => 42;
+}
+
+class C extends A<self.A> with M {}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_32182.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_32182.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f0f5e79
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_32182.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+import "issue_32182.dart" as self;
+
+class A<T> {}
+
+class C extends A<self.A> with M {}
+
+class M {
+ m() => 42;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_32196.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_32196.dart.textual_outline.expect
new file mode 100644
index 0000000..7fecce8
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_32196.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class A {
+ final String name;
+ A.get(this.name);
+ A.set(this.name);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_32196.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_32196.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..13664b5
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_32196.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class A {
+ A.get(this.name);
+ A.set(this.name);
+ final String name;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_32200.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_32200.dart.textual_outline.expect
new file mode 100644
index 0000000..7912167
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_32200.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+import "issue_32200.dart" as self;
+
+class Foo {
+ self.Foo self;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_32200.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_32200.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7912167
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_32200.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+import "issue_32200.dart" as self;
+
+class Foo {
+ self.Foo self;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_32660.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_32660.dart.textual_outline.expect
new file mode 100644
index 0000000..07c64a4
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_32660.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+class A {
+ foo(int x) => x;
+}
+
+class B {
+ foo(int x, {int y}) => y;
+}
+
+class C extends A implements B {
+ noSuchMethod(i) {}
+}
+
+class D {
+ foo(int x) => x;
+}
+
+class E extends D {
+ foo(int x, {int y});
+ noSuchMethod(i) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_32660.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_32660.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..07c64a4
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_32660.dart.textual_outline_modelled.expect
@@ -0,0 +1,22 @@
+class A {
+ foo(int x) => x;
+}
+
+class B {
+ foo(int x, {int y}) => y;
+}
+
+class C extends A implements B {
+ noSuchMethod(i) {}
+}
+
+class D {
+ foo(int x) => x;
+}
+
+class E extends D {
+ foo(int x, {int y});
+ noSuchMethod(i) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_32972.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_32972.dart.textual_outline.expect
new file mode 100644
index 0000000..afd767f
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_32972.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+void foo<X>(X i) {}
+
+class Foo {
+ static foo<X>(X i) {}
+ bar<X>(X i) {}
+}
+
+class Bar<X, Y> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_32972.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_32972.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..fedb95a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_32972.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+class Bar<X, Y> {}
+
+class Foo {
+ bar<X>(X i) {}
+ static foo<X>(X i) {}
+}
+
+main() {}
+void foo<X>(X i) {}
diff --git a/pkg/front_end/testcases/regress/issue_33452.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_33452.dart.textual_outline.expect
new file mode 100644
index 0000000..eff2983
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_33452.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class ExistingClass {
+ ExistingClass.existingConstructor();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_33452.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_33452.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..eff2983
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_33452.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+class ExistingClass {
+ ExistingClass.existingConstructor();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_33672.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_33672.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_33672.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_33672.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_33672.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_33672.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_34225.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_34225.dart.textual_outline.expect
new file mode 100644
index 0000000..587ce92
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_34225.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class C {
+ static set C(v) { }
+}
+class D {
+ set D(v) { }
+}
+main() { }
diff --git a/pkg/front_end/testcases/regress/issue_34291.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_34291.dart.textual_outline.expect
new file mode 100644
index 0000000..0019a54
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_34291.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+import "issue_34291_lib.dart" as lib;
+
+class B {}
+
+lib.A<B> foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_34291.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_34291.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0019a54
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_34291.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+import "issue_34291_lib.dart" as lib;
+
+class B {}
+
+lib.A<B> foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_34403.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_34403.dart.textual_outline.expect
new file mode 100644
index 0000000..6ec803e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_34403.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+import 'issue_34403_lib.dart' as p;
+
+class C<T> {
+ C.bar();
+}
+
+class D<T> {
+ const D.foo();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_34403.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_34403.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6ec803e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_34403.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+import 'issue_34403_lib.dart' as p;
+
+class C<T> {
+ C.bar();
+}
+
+class D<T> {
+ const D.foo();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_34498.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_34498.dart.textual_outline.expect
new file mode 100644
index 0000000..cc0607c
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_34498.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+import 'issue_34498_lib.dart' as lib;
+
+class A {
+ lib.MyClass get lib => null;
+ foo foo() {}
+ Missing bar() {}
+}
+
+class B extends A {}
+
+final A a = null;
+
+class C<T> {
+ T<String> foo() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_34498.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_34498.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a3837b8
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_34498.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+import 'issue_34498_lib.dart' as lib;
+
+class A {
+ Missing bar() {}
+ foo foo() {}
+ lib.MyClass get lib => null;
+}
+
+class B extends A {}
+
+class C<T> {
+ T<String> foo() {}
+}
+
+final A a = null;
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_34563.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_34563.dart.textual_outline.expect
new file mode 100644
index 0000000..e2de5d8
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_34563.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+mixin M1 {
+ int get m => 1;
+}
+mixin M2 extend M1 {
+}
+mixin M3 extends M1 {
+}
+class C1 {
+ int get c => 2;
+}
+class C2 extend C1 with M2 {
+}
+class C3 on C1 with M3 {
+}
+main() { }
diff --git a/pkg/front_end/testcases/regress/issue_34610.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_34610.dart.textual_outline.expect
new file mode 100644
index 0000000..cd96318
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_34610.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+class A {
+ get A.named ()=> null;
+ get bar => 1;
+}
+class B {
+ B.named (): super();
+ get bar => 1;
+}
+class C {
+ C.named ()=> null;
+ get bar => 1;
+}
+main() { }
diff --git a/pkg/front_end/testcases/regress/issue_34614.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_34614.dart.textual_outline.expect
new file mode 100644
index 0000000..d25190b
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_34614.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class C {
+ C. ( ){ }
+}
+main() { }
diff --git a/pkg/front_end/testcases/regress/issue_34850.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_34850.dart.textual_outline.expect
new file mode 100644
index 0000000..ce8cb35
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_34850.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+<
+foo< int >f1() { }
+foo Future<List<int>> ( ){ }
+f2() async => null;
+Future<List<>> f3() async { }
+main() async { }
diff --git a/pkg/front_end/testcases/regress/issue_35151.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_35151.dart.textual_outline.expect
new file mode 100644
index 0000000..24a2200
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_35151.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class A {
+ int a;
+}
+class B extends A {
+ B() : super.a = 42;
+}
+class C {
+ C() : super = 42;
+}
+main() { }
diff --git a/pkg/front_end/testcases/regress/issue_35177.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_35177.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_35177.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_35177.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_35177.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_35177.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_35213.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_35213.dart.textual_outline.expect
new file mode 100644
index 0000000..55bc6cb
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_35213.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+f(int a, int b) {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_35213.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_35213.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..55bc6cb
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_35213.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+f(int a, int b) {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_35220.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_35220.dart.textual_outline.expect
new file mode 100644
index 0000000..81e059b
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_35220.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class A {
+ A bad() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_35220.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_35220.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..81e059b
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_35220.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+class A {
+ A bad() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_35258.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_35258.dart.textual_outline.expect
new file mode 100644
index 0000000..639a601
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_35258.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+main() {}
+
+class C {
+ final d;
+ C() {}
+ C(this.d) {}
+}
diff --git a/pkg/front_end/testcases/regress/issue_35258.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_35258.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f4d4891
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_35258.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class C {
+ C() {}
+ C(this.d) {}
+ final d;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_35259.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_35259.dart.textual_outline.expect
new file mode 100644
index 0000000..a47d649
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_35259.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+class Supertype {
+ factory Supertype() = Unresolved;
+ factory Supertype() = Unresolved;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_35259.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_35259.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a47d649
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_35259.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+class Supertype {
+ factory Supertype() = Unresolved;
+ factory Supertype() = Unresolved;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_35260.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_35260.dart.textual_outline.expect
new file mode 100644
index 0000000..beaef36
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_35260.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class Supertype {
+ factory Supertype() = X;
+ factory Supertype() = X;
+}
+
+class X implements Supertype {
+ X();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_35260.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_35260.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..beaef36
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_35260.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+class Supertype {
+ factory Supertype() = X;
+ factory Supertype() = X;
+}
+
+class X implements Supertype {
+ X();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_35266.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_35266.dart.textual_outline.expect
new file mode 100644
index 0000000..1d6a7d0
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_35266.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+class B<T> extends C<T> {
+ B();
+ factory B.foo() = B<T>;
+ factory B.foo() = B<T>;
+}
+
+class C<K> {
+ C();
+ factory C.bar() = B<K>.foo;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_35266.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_35266.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1d6a7d0
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_35266.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+class B<T> extends C<T> {
+ B();
+ factory B.foo() = B<T>;
+ factory B.foo() = B<T>;
+}
+
+class C<K> {
+ C();
+ factory C.bar() = B<K>.foo;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_36400.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_36400.dart.textual_outline.expect
new file mode 100644
index 0000000..8317039
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_36400.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+class Test {
+ Test factory Test() { }
+}
diff --git a/pkg/front_end/testcases/regress/issue_36647.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_36647.dart.textual_outline.expect
new file mode 100644
index 0000000..489c840
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_36647.dart.textual_outline.expect
@@ -0,0 +1 @@
+import 'issue_36647_lib1.dart';
diff --git a/pkg/front_end/testcases/regress/issue_36647.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_36647.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..489c840
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_36647.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+import 'issue_36647_lib1.dart';
diff --git a/pkg/front_end/testcases/regress/issue_36647_2.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_36647_2.dart.textual_outline.expect
new file mode 100644
index 0000000..f3a511c
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_36647_2.dart.textual_outline.expect
@@ -0,0 +1 @@
+export 'issue_36647_2_lib1.dart';
diff --git a/pkg/front_end/testcases/regress/issue_36647_2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_36647_2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f3a511c
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_36647_2.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+export 'issue_36647_2_lib1.dart';
diff --git a/pkg/front_end/testcases/regress/issue_36669.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_36669.dart.textual_outline.expect
new file mode 100644
index 0000000..6cdd387
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_36669.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+class NoUnnamedConstuctor {
+ NoUnnamedConstuctor._();
+}
+
+class MixMeIn {}
+
+class Foo extends NoUnnamedConstuctor with MixMeIn {}
diff --git a/pkg/front_end/testcases/regress/issue_36669.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_36669.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c4b4f56
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_36669.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+class Foo extends NoUnnamedConstuctor with MixMeIn {}
+
+class MixMeIn {}
+
+class NoUnnamedConstuctor {
+ NoUnnamedConstuctor._();
+}
diff --git a/pkg/front_end/testcases/regress/issue_36793.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_36793.dart.textual_outline.expect
new file mode 100644
index 0000000..b3d1993
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_36793.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+const int y = 42;
+@y
+int x = 1;
+@y
+int x = 2;
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_36793.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_36793.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..aefe023
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_36793.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+@y
+int x = 1;
+@y
+int x = 2;
+const int y = 42;
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_37285.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_37285.dart.textual_outline.expect
new file mode 100644
index 0000000..9feb16a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_37285.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class C {
+ C() : super()[];
+}
+main () { }
diff --git a/pkg/front_end/testcases/regress/issue_37681.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_37681.dart.textual_outline.expect
new file mode 100644
index 0000000..386f405
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_37681.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() async {}
diff --git a/pkg/front_end/testcases/regress/issue_37681.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_37681.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..386f405
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_37681.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() async {}
diff --git a/pkg/front_end/testcases/regress/issue_39040.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_39040.dart.textual_outline.expect
new file mode 100644
index 0000000..ab73b3a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_39040.dart.textual_outline.expect
@@ -0,0 +1 @@
+void main() {}
diff --git a/pkg/front_end/testcases/regress/issue_39040.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_39040.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ab73b3a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_39040.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+void main() {}
diff --git a/pkg/front_end/testcases/regress/issue_39091_1.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_39091_1.dart.textual_outline.expect
new file mode 100644
index 0000000..943e3f5
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_39091_1.dart.textual_outline.expect
@@ -0,0 +1 @@
+hello;
diff --git a/pkg/front_end/testcases/regress/issue_39682.dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_39682.dart.textual_outline.expect
new file mode 100644
index 0000000..1d2a6fb
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_39682.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import "issue_39682_lib.dart" deferred as foo;
+
+main() {}
+String __loadLibrary_foo() {}
diff --git a/pkg/front_end/testcases/regress/issue_39682.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/regress/issue_39682.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ea21c2f
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_39682.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import "issue_39682_lib.dart" deferred as foo;
+
+String __loadLibrary_foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_41265.crash_dart.textual_outline.expect b/pkg/front_end/testcases/regress/issue_41265.crash_dart.textual_outline.expect
new file mode 100644
index 0000000..0ebe3c9
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_41265.crash_dart.textual_outline.expect
@@ -0,0 +1 @@
+class A<T> {} mixin M<T> {} class DND1 extends Object with M<dynamic> Function()> { } class DND2 extends Object with M<dynamic> Function() { } class DND3 extends M<dynamic> Function() { } class DND4 implements M<dynamic> Function() { } main() { }
diff --git a/pkg/front_end/testcases/regress/utf_16_le_content.crash_dart.strong.expect b/pkg/front_end/testcases/regress/utf_16_le_content.crash_dart.strong.expect
new file mode 100644
index 0000000..03dca82
--- /dev/null
+++ b/pkg/front_end/testcases/regress/utf_16_le_content.crash_dart.strong.expect
Binary files differ
diff --git a/pkg/front_end/testcases/regress/utf_16_le_content.crash_dart.strong.transformed.expect b/pkg/front_end/testcases/regress/utf_16_le_content.crash_dart.strong.transformed.expect
new file mode 100644
index 0000000..03dca82
--- /dev/null
+++ b/pkg/front_end/testcases/regress/utf_16_le_content.crash_dart.strong.transformed.expect
Binary files differ
diff --git a/pkg/front_end/testcases/runtime_checks/call_kinds.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/call_kinds.dart.textual_outline.expect
new file mode 100644
index 0000000..de4942d
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/call_kinds.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+typedef void F();
+
+class C {
+ void f() {}
+ F get g => null;
+ dynamic get h => null;
+ void test() {}
+}
+
+void test(C c, F f, dynamic d) {}
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/call_kinds.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/call_kinds.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..078b15a
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/call_kinds.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+class C {
+ F get g => null;
+ dynamic get h => null;
+ void f() {}
+ void test() {}
+}
+
+main() {}
+typedef void F();
+void test(C c, F f, dynamic d) {}
diff --git a/pkg/front_end/testcases/runtime_checks/call_kinds_get.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/call_kinds_get.dart.textual_outline.expect
new file mode 100644
index 0000000..aaf824e
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/call_kinds_get.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C {
+ dynamic get x => null;
+ dynamic y;
+ void test() {}
+}
+
+void test(C c, dynamic d) {}
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/call_kinds_get.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/call_kinds_get.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..588c9cd
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/call_kinds_get.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C {
+ dynamic get x => null;
+ dynamic y;
+ void test() {}
+}
+
+main() {}
+void test(C c, dynamic d) {}
diff --git a/pkg/front_end/testcases/runtime_checks/call_kinds_set.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/call_kinds_set.dart.textual_outline.expect
new file mode 100644
index 0000000..c96f079
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/call_kinds_set.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C {
+ void set x(dynamic value) {}
+ dynamic y;
+ void test() {}
+}
+
+void test(C c, dynamic d) {}
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/call_kinds_set.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/call_kinds_set.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1ea93b3
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/call_kinds_set.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C {
+ dynamic y;
+ void set x(dynamic value) {}
+ void test() {}
+}
+
+main() {}
+void test(C c, dynamic d) {}
diff --git a/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off.dart.textual_outline.expect
new file mode 100644
index 0000000..acd8a15
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+ void call() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..acd8a15
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+ void call() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off_future_or.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off_future_or.dart.textual_outline.expect
new file mode 100644
index 0000000..c9eba70
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off_future_or.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+import 'dart:async';
+
+class C {
+ void call() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off_future_or.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off_future_or.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c9eba70
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off_future_or.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+import 'dart:async';
+
+class C {
+ void call() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_field.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/contravariant_field.dart.textual_outline.expect
new file mode 100644
index 0000000..8d81028
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_field.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+typedef void F<T>(T x);
+
+class C<T> {
+ F<T> y;
+ void f() {}
+}
+
+void g(C<num> c) {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_field.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/contravariant_field.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..54efdb7
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_field.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C<T> {
+ F<T> y;
+ void f() {}
+}
+
+typedef void F<T>(T x);
+void g(C<num> c) {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.textual_outline.expect
new file mode 100644
index 0000000..3bc94cd
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+typedef void F<T>(T t);
+
+class C<T> {
+ void f<U extends F<T>>(U x) {}
+}
+
+void g(C<num> c) {}
+void test() {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d45149c
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C<T> {
+ void f<U extends F<T>>(U x) {}
+}
+
+typedef void F<T>(T t);
+void g(C<num> c) {}
+void main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_return.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return.dart.textual_outline.expect
new file mode 100644
index 0000000..dc2912a
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+typedef void F<T>(T x);
+
+class C<T> {
+ F<T> f1() {}
+ List<F<T>> f2() {}
+}
+
+void g1(C<num> c) {}
+void g2(C<num> c) {}
+void g3(C<num> c) {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_return.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6c35eb5
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+class C<T> {
+ F<T> f1() {}
+ List<F<T>> f2() {}
+}
+
+typedef void F<T>(T x);
+void g1(C<num> c) {}
+void g2(C<num> c) {}
+void g3(C<num> c) {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_null_aware.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_null_aware.dart.textual_outline.expect
new file mode 100644
index 0000000..dc2912a
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_null_aware.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+typedef void F<T>(T x);
+
+class C<T> {
+ F<T> f1() {}
+ List<F<T>> f2() {}
+}
+
+void g1(C<num> c) {}
+void g2(C<num> c) {}
+void g3(C<num> c) {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_null_aware.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_null_aware.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6c35eb5
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_null_aware.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+class C<T> {
+ F<T> f1() {}
+ List<F<T>> f2() {}
+}
+
+typedef void F<T>(T x);
+void g1(C<num> c) {}
+void g2(C<num> c) {}
+void g3(C<num> c) {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_tear_off.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_tear_off.dart.textual_outline.expect
new file mode 100644
index 0000000..950b57d
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_tear_off.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+typedef void F<T>(T x);
+typedef F<T> G<T>();
+
+class C<T> {
+ F<T> _x;
+ C(this._x);
+ F<T> f() => _x;
+}
+
+G<num> g(C<num> c) {}
+void h(int i) {}
+void test() {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_tear_off.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_tear_off.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ac397a4
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_tear_off.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+G<num> g(C<num> c) {}
+
+class C<T> {
+ C(this._x);
+ F<T> _x;
+ F<T> f() => _x;
+}
+
+typedef F<T> G<T>();
+typedef void F<T>(T x);
+void h(int i) {}
+void main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_getter.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/contravariant_getter.dart.textual_outline.expect
new file mode 100644
index 0000000..69264e5
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_getter.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+typedef void F<T>(T x);
+
+class C<T> {
+ F<T> y;
+ void f(T value) {}
+}
+
+void g(C<num> c) {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_getter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/contravariant_getter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f9b4c27
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_getter.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C<T> {
+ F<T> y;
+ void f(T value) {}
+}
+
+typedef void F<T>(T x);
+void g(C<num> c) {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_getter_return.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return.dart.textual_outline.expect
new file mode 100644
index 0000000..c87589e
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+typedef void F<T>(T x);
+
+class C<T> {
+ F<T> get f1 => null;
+ List<F<T>> get f2 {}
+}
+
+void g1(C<num> c) {}
+void g2(C<num> c) {}
+void g3(C<num> c) {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_getter_return.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bc0e76e
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+class C<T> {
+ F<T> get f1 => null;
+ List<F<T>> get f2 {}
+}
+
+typedef void F<T>(T x);
+void g1(C<num> c) {}
+void g2(C<num> c) {}
+void g3(C<num> c) {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_getter_return_null_aware.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return_null_aware.dart.textual_outline.expect
new file mode 100644
index 0000000..c87589e
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return_null_aware.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+typedef void F<T>(T x);
+
+class C<T> {
+ F<T> get f1 => null;
+ List<F<T>> get f2 {}
+}
+
+void g1(C<num> c) {}
+void g2(C<num> c) {}
+void g3(C<num> c) {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_getter_return_null_aware.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return_null_aware.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bc0e76e
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return_null_aware.dart.textual_outline_modelled.expect
@@ -0,0 +1,12 @@
+library test;
+
+class C<T> {
+ F<T> get f1 => null;
+ List<F<T>> get f2 {}
+}
+
+typedef void F<T>(T x);
+void g1(C<num> c) {}
+void g2(C<num> c) {}
+void g3(C<num> c) {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.textual_outline.expect
new file mode 100644
index 0000000..066813e
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C<T> {
+ void f<U extends T>(U x) {}
+ void g1<U extends T>() {}
+}
+
+void g2(C<Object> c) {}
+void test() {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0bbb372
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C<T> {
+ void f<U extends T>(U x) {}
+ void g1<U extends T>() {}
+}
+
+void g2(C<Object> c) {}
+void main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter.dart.textual_outline.expect
new file mode 100644
index 0000000..9eb7363
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C<T> {
+ void f(T x) {}
+}
+
+void g1(C<num> c) {}
+void g2(C<int> c) {}
+void g3(C<num> c) {}
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a772405
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C<T> {
+ void f(T x) {}
+}
+
+main() {}
+void g1(C<num> c) {}
+void g2(C<int> c) {}
+void g3(C<num> c) {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_complex.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_complex.dart.textual_outline.expect
new file mode 100644
index 0000000..be90d87
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_complex.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+library test;
+
+class C<T> {
+ void f1(List<T> x) {}
+ void f2(T callback()) {}
+ void f3(T callback(T x)) {}
+ void f4(void callback(T x)) {}
+}
+
+void g1(C<num> c, List<num> l) {}
+void g2(C<num> c, num callback()) {}
+void g3(C<num> c, num callback(num x)) {}
+void g4(C<num> c, void callback(num x)) {}
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_complex.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_complex.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9b83d94
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_complex.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+library test;
+
+class C<T> {
+ void f1(List<T> x) {}
+ void f2(T callback()) {}
+ void f3(T callback(T x)) {}
+ void f4(void callback(T x)) {}
+}
+
+main() {}
+void g1(C<num> c, List<num> l) {}
+void g2(C<num> c, num callback()) {}
+void g3(C<num> c, num callback(num x)) {}
+void g4(C<num> c, void callback(num x)) {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.textual_outline.expect
new file mode 100644
index 0000000..51601b9
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.textual_outline.expect
@@ -0,0 +1,24 @@
+library test;
+
+abstract class I<T> {
+ void f1(T x);
+ void f2(T x);
+}
+
+class C<U> implements I<int> {
+ void f1(int x) {}
+ void f2(int x, [U y]) {}
+}
+
+class D<U> extends C<U> {
+ void f1(int x) {}
+ void f2(int x, [U y]) {}
+}
+
+void g1(C<num> c) {}
+void g2(I<num> i) {}
+void g3(C<num> c) {}
+void g4(D<num> d) {}
+void g5(D<num> d) {}
+void test() {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..15e7d8a
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.textual_outline_modelled.expect
@@ -0,0 +1,24 @@
+library test;
+
+abstract class I<T> {
+ void f1(T x);
+ void f2(T x);
+}
+
+class C<U> implements I<int> {
+ void f1(int x) {}
+ void f2(int x, [U y]) {}
+}
+
+class D<U> extends C<U> {
+ void f1(int x) {}
+ void f2(int x, [U y]) {}
+}
+
+void g1(C<num> c) {}
+void g2(I<num> i) {}
+void g3(C<num> c) {}
+void g4(D<num> d) {}
+void g5(D<num> d) {}
+void main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.textual_outline.expect
new file mode 100644
index 0000000..7d6cf9b
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+library test;
+
+class B {
+ void f(int x) {}
+}
+
+abstract class I<T> {
+ void f(T x);
+}
+
+class M {
+ void f(int x) {}
+}
+
+class C = B with M implements I<int>;
+void g1(C c) {}
+void g2(I<num> i) {}
+void test() {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b47acf4
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+library test;
+
+abstract class I<T> {
+ void f(T x);
+}
+
+class B {
+ void f(int x) {}
+}
+
+class M {
+ void f(int x) {}
+}
+
+class C = B with M implements I<int>;
+void g1(C c) {}
+void g2(I<num> i) {}
+void main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.textual_outline.expect
new file mode 100644
index 0000000..1995799
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+library test;
+
+class B {
+ void f(int x) {}
+}
+
+abstract class I<T> {
+ void f(T x);
+}
+
+class C extends B implements I<int> {}
+
+void g1(C c) {}
+void g2(I<num> i) {}
+void test() {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..da6ecc9
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+library test;
+
+abstract class I<T> {
+ void f(T x);
+}
+
+class B {
+ void f(int x) {}
+}
+
+class C extends B implements I<int> {}
+
+void g1(C c) {}
+void g2(I<num> i) {}
+void main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.textual_outline.expect
new file mode 100644
index 0000000..ef098bf
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+library test;
+
+class B {
+ void f(int x) {}
+}
+
+abstract class I<T> {
+ void f(T x);
+}
+
+class M {}
+
+class C = B with M implements I<int>;
+void g1(C c) {}
+void g2(I<num> i) {}
+void test() {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8f80a0b
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+library test;
+
+abstract class I<T> {
+ void f(T x);
+}
+
+class B {
+ void f(int x) {}
+}
+
+class M {}
+
+class C = B with M implements I<int>;
+void g1(C c) {}
+void g2(I<num> i) {}
+void main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_tear_off.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_tear_off.dart.textual_outline.expect
new file mode 100644
index 0000000..86fd3b6
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_tear_off.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+typedef void F<T>(T x);
+typedef U G<T, U>(T x);
+
+class C<T> {
+ void f1(T x) {}
+ T f2(List<T> x) => x.first;
+}
+
+F<num> g1(C<num> c) {}
+void g2(C<int> c, Object x) {}
+G<List<num>, num> g3(C<num> c) {}
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_tear_off.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_tear_off.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c813f8d
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_tear_off.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+F<num> g1(C<num> c) {}
+G<List<num>, num> g3(C<num> c) {}
+
+class C<T> {
+ T f2(List<T> x) => x.first;
+ void f1(T x) {}
+}
+
+main() {}
+typedef U G<T, U>(T x);
+typedef void F<T>(T x);
+void g2(C<int> c, Object x) {}
+void test() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.textual_outline.expect
new file mode 100644
index 0000000..a0211e4
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.textual_outline.expect
@@ -0,0 +1,20 @@
+library test;
+
+typedef F<T>(T x);
+
+class C {
+ void f(num x) {}
+}
+
+class D extends C {
+ void f(covariant int x) {}
+}
+
+class E extends D {
+ void f(int x) {}
+}
+
+void g1(C c) {}
+F<num> g2(C c) {}
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7b38b24
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.textual_outline_modelled.expect
@@ -0,0 +1,20 @@
+library test;
+
+F<num> g2(C c) {}
+
+class C {
+ void f(num x) {}
+}
+
+class D extends C {
+ void f(covariant int x) {}
+}
+
+class E extends D {
+ void f(int x) {}
+}
+
+main() {}
+test() {}
+typedef F<T>(T x);
+void g1(C c) {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.textual_outline.expect
new file mode 100644
index 0000000..42ad63f
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+class C {
+ num x;
+}
+
+class D implements C {
+ covariant int x;
+}
+
+class E implements D {
+ int x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..42ad63f
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+class C {
+ num x;
+}
+
+class D implements C {
+ covariant int x;
+}
+
+class E implements D {
+ int x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.textual_outline.expect
new file mode 100644
index 0000000..0e97340
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.textual_outline.expect
@@ -0,0 +1,16 @@
+library test;
+
+class C {
+ num x;
+}
+
+class D implements C {
+ covariant int x;
+}
+
+class E implements D {
+ int get x => 0;
+ void set x(int value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0e97340
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+library test;
+
+class C {
+ num x;
+}
+
+class D implements C {
+ covariant int x;
+}
+
+class E implements D {
+ int get x => 0;
+ void set x(int value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.textual_outline.expect
new file mode 100644
index 0000000..3e18946
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+class C {
+ void set x(num value) {}
+}
+
+class D extends C {
+ void set x(covariant int value) {}
+}
+
+class E extends D {
+ void set x(int value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3e18946
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+class C {
+ void set x(num value) {}
+}
+
+class D extends C {
+ void set x(covariant int value) {}
+}
+
+class E extends D {
+ void set x(int value) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.textual_outline.expect
new file mode 100644
index 0000000..335e47d
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+class C {
+ void set x(num value) {}
+}
+
+class D extends C {
+ void set x(covariant int value) {}
+}
+
+class E implements D {
+ int x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..335e47d
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+class C {
+ void set x(num value) {}
+}
+
+class D extends C {
+ void set x(covariant int value) {}
+}
+
+class E implements D {
+ int x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_setter.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_setter.dart.textual_outline.expect
new file mode 100644
index 0000000..b8c3d2f
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_setter.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+library test;
+
+typedef void F<T>(T x);
+
+class C<T> {
+ T x;
+ void set y(T value) {}
+ void f(T value) {}
+}
+
+void g(C<num> c) {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_setter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/covariant_setter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b7e0f42
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_setter.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C<T> {
+ T x;
+ void f(T value) {}
+ void set y(T value) {}
+}
+
+typedef void F<T>(T x);
+void g(C<num> c) {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.textual_outline.expect
new file mode 100644
index 0000000..3385f7f
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+class C<T> {
+ void f1(T x) {}
+ void f2(int x) {}
+}
+
+class D extends C<num> {
+ void f1(covariant int x) {}
+}
+
+void g1(dynamic d) {}
+void g2(dynamic d) {}
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..89135dc
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+class C<T> {
+ void f1(T x) {}
+ void f2(int x) {}
+}
+
+class D extends C<num> {
+ void f1(covariant int x) {}
+}
+
+main() {}
+void g1(dynamic d) {}
+void g2(dynamic d) {}
+void test() {}
diff --git a/pkg/front_end/testcases/runtime_checks/dynamic_invocation_generic.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/dynamic_invocation_generic.dart.textual_outline.expect
new file mode 100644
index 0000000..3ab451a
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/dynamic_invocation_generic.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C<T> {
+ void f<U extends T>(U x) {}
+}
+
+void g1(dynamic d) {}
+void g2(dynamic d) {}
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/dynamic_invocation_generic.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/dynamic_invocation_generic.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cc44c99
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/dynamic_invocation_generic.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+class C<T> {
+ void f<U extends T>(U x) {}
+}
+
+main() {}
+void g1(dynamic d) {}
+void g2(dynamic d) {}
+void test() {}
diff --git a/pkg/front_end/testcases/runtime_checks/dynamic_invocation_of_getter.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/dynamic_invocation_of_getter.dart.textual_outline.expect
new file mode 100644
index 0000000..7737325
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/dynamic_invocation_of_getter.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C {
+ dynamic f;
+ C(this.f);
+}
+
+void g(C c) {}
+void h(int i) {}
+void test() {}
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/dynamic_invocation_of_getter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/dynamic_invocation_of_getter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4e49871
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/dynamic_invocation_of_getter.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+class C {
+ C(this.f);
+ dynamic f;
+}
+
+main() {}
+void g(C c) {}
+void h(int i) {}
+void test() {}
diff --git a/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.textual_outline.expect
new file mode 100644
index 0000000..8c4b40b
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+class B<T> {
+ T x;
+}
+
+class C {
+ num x;
+}
+
+class D extends C implements B<num> {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8c4b40b
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+class B<T> {
+ T x;
+}
+
+class C {
+ num x;
+}
+
+class D extends C implements B<num> {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.textual_outline.expect
new file mode 100644
index 0000000..289a96e
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+library test;
+
+class B {
+ Object _x;
+ void f([num x = 10]) {}
+ void g({num x = 20}) {}
+ void check(Object expectedValue) {}
+}
+
+abstract class I<T> {
+ void f([T x]);
+ void g({T x});
+}
+
+class C extends B implements I<num> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1ca314d
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+library test;
+
+abstract class I<T> {
+ void f([T x]);
+ void g({T x});
+}
+
+class B {
+ Object _x;
+ void check(Object expectedValue) {}
+ void f([num x = 10]) {}
+ void g({num x = 20}) {}
+}
+
+class C extends B implements I<num> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.textual_outline.expect
new file mode 100644
index 0000000..8c6231b
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+class B {
+ void f(int x, int y) {}
+}
+
+abstract class I<T> {
+ void f(T x, int y);
+}
+
+class C extends B implements I<int> {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..345dc98
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+abstract class I<T> {
+ void f(T x, int y);
+}
+
+class B {
+ void f(int x, int y) {}
+}
+
+class C extends B implements I<int> {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.textual_outline.expect
new file mode 100644
index 0000000..04e6489
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+library test;
+
+class C<T> {
+ void set x(T t) {}
+ T y;
+}
+
+class D implements C<num> {
+ num x;
+ num y;
+}
+
+class E implements C<num> {
+ void set x(num t) {}
+ num get y => null;
+ void set y(num t) {}
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8d40bf2
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+library test;
+
+class C<T> {
+ T y;
+ void set x(T t) {}
+}
+
+class D implements C<num> {
+ num x;
+ num y;
+}
+
+class E implements C<num> {
+ num get y => null;
+ void set x(num t) {}
+ void set y(num t) {}
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.textual_outline.expect
new file mode 100644
index 0000000..9423c72
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+library test;
+
+abstract class A {
+ void set x(covariant Object value);
+}
+
+class B implements A {
+ void f(covariant Object x) {}
+ Object x;
+}
+
+class C<T> implements B {
+ void f(T x) {}
+ T x;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..49de95f
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+library test;
+
+abstract class A {
+ void set x(covariant Object value);
+}
+
+class B implements A {
+ Object x;
+ void f(covariant Object x) {}
+}
+
+class C<T> implements B {
+ T x;
+ void f(T x) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..1c0e505
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_initializer.dart.textual_outline.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+ C(Object o) : assert(o);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_initializer.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_initializer.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1c0e505
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_initializer.dart.textual_outline_modelled.expect
@@ -0,0 +1,7 @@
+library test;
+
+class C {
+ C(Object o) : assert(o);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_statement.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_statement.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_statement.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_statement.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_statement.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_statement.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_constructor_initializer.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_constructor_initializer.dart.textual_outline.expect
new file mode 100644
index 0000000..5767080
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_constructor_initializer.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C {
+ bool b;
+ C(Object o) : b = o;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_constructor_initializer.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_constructor_initializer.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..37e2b22
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_constructor_initializer.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+library test;
+
+class C {
+ C(Object o) : b = o;
+ bool b;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_do.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_do.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_do.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_do.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_do.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_do.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_for_condition.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_for_condition.dart.textual_outline.expect
new file mode 100644
index 0000000..c07c403
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_for_condition.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_for_condition.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_for_condition.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c07c403
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_for_condition.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_if.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_if.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_if.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_if.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_if.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_if.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_not.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_not.dart.textual_outline.expect
new file mode 100644
index 0000000..c07c403
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_not.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_not.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_not.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c07c403
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_not.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_while.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_while.dart.textual_outline.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_while.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_while.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_while.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d0b557f
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_while.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+library test;
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.textual_outline.expect
new file mode 100644
index 0000000..84c7157
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+class B {
+ void f(num x) {}
+}
+
+abstract class I<T> {
+ void f(T x);
+}
+
+class C extends B implements I<num> {
+ void f(num x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..168422a
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+library test;
+
+abstract class I<T> {
+ void f(T x);
+}
+
+class B {
+ void f(num x) {}
+}
+
+class C extends B implements I<num> {
+ void f(num x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.textual_outline.expect
new file mode 100644
index 0000000..6c7fe09
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.textual_outline.expect
@@ -0,0 +1,20 @@
+library test;
+
+typedef F<T>(T x);
+
+class C<T> {
+ void f(T x) {}
+ void g1(T x) {}
+ void g2(T x) {}
+ void g3(C<T> c, T x) {}
+ F<T> g4() => this.f;
+}
+
+class D extends C<int> {}
+
+class E extends C<num> {
+ void f(covariant int x) {}
+}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a210365
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+library test;
+
+class C<T> {
+ F<T> g4() => this.f;
+ void f(T x) {}
+ void g1(T x) {}
+ void g2(T x) {}
+ void g3(C<T> c, T x) {}
+}
+
+class D extends C<int> {}
+
+class E extends C<num> {
+ void f(covariant int x) {}
+}
+
+main() {}
+test() {}
+typedef F<T>(T x);
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_combiner.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_combiner.dart.textual_outline.expect
new file mode 100644
index 0000000..bd7aa707
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_combiner.dart.textual_outline.expect
@@ -0,0 +1,20 @@
+library test;
+
+typedef void F<T>(T x);
+
+class B<T, U extends F<T>> {
+ B<T, F<T>> operator +(other) => null;
+}
+
+class C {
+ B<num, F<num>> x;
+ static B<num, F<num>> y;
+ B<num, F<num>> operator [](int i) => null;
+ void operator []=(int i, B<num, F<num>> v) {}
+}
+
+void test1(B<num, F<num>> b) {}
+void test2(C c) {}
+void test3(C c) {}
+void test4(C c) {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_combiner.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_combiner.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..231976b
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_combiner.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+library test;
+
+class B<T, U extends F<T>> {
+ B<T, F<T>> operator +(other) => null;
+}
+
+class C {
+ B<num, F<num>> operator [](int i) => null;
+ B<num, F<num>> x;
+ static B<num, F<num>> y;
+ void operator []=(int i, B<num, F<num>> v) {}
+}
+
+typedef void F<T>(T x);
+void main() {}
+void test1(B<num, F<num>> b) {}
+void test2(C c) {}
+void test3(C c) {}
+void test4(C c) {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.textual_outline.expect
new file mode 100644
index 0000000..c331f05
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+library test;
+
+void expectTypeError(void callback()) {}
+void expect(Object value, Object expected) {}
+
+class C<T> {
+ C(this.plusResult);
+ final num Function(T) plusResult;
+ num Function(T) operator +(int i) => plusResult;
+}
+
+class D {
+ D(this.getValue);
+ final C<num> getValue;
+ C<num> get value => getValue;
+ int Function(int) setValue;
+ void set value(int Function(int) value) {}
+}
+
+int numToInt(num n) => 1;
+num numToNum(num n) => 2;
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c2c9d06
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.textual_outline_modelled.expect
@@ -0,0 +1,21 @@
+library test;
+
+class C<T> {
+ C(this.plusResult);
+ final num Function(T) plusResult;
+ num Function(T) operator +(int i) => plusResult;
+}
+
+class D {
+ C<num> get value => getValue;
+ D(this.getValue);
+ final C<num> getValue;
+ int Function(int) setValue;
+ void set value(int Function(int) value) {}
+}
+
+int numToInt(num n) => 1;
+num numToNum(num n) => 2;
+void expect(Object value, Object expected) {}
+void expectTypeError(void callback()) {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.textual_outline.expect
new file mode 100644
index 0000000..b03de79
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+typedef void F<T>(T x);
+
+class B<T> {
+ B<T> operator +(B<T> other) => null;
+}
+
+class C<T> {
+ B<F<T>> get x => null;
+ void set x(B<F<T>> value) {}
+}
+
+void test(C<num> c) {}
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2e87293
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+library test;
+
+class B<T> {
+ B<T> operator +(B<T> other) => null;
+}
+
+class C<T> {
+ B<F<T>> get x => null;
+ void set x(B<F<T>> value) {}
+}
+
+main() {}
+typedef void F<T>(T x);
+void test(C<num> c) {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_index_assign.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_assign.dart.textual_outline.expect
new file mode 100644
index 0000000..63f05d9
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_assign.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+library test;
+
+typedef void F<T>(T x);
+
+class B<T> {
+ B<T> operator +(B<T> other) => null;
+}
+
+class C<T> {
+ B<F<T>> operator [](int i) => null;
+ void operator []=(int i, B<F<T>> x) {}
+}
+
+void test(C<num> c) {}
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_index_assign.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_assign.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ee8f9fa
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_assign.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+library test;
+
+class B<T> {
+ B<T> operator +(B<T> other) => null;
+}
+
+class C<T> {
+ B<F<T>> operator [](int i) => null;
+ void operator []=(int i, B<F<T>> x) {}
+}
+
+main() {}
+typedef void F<T>(T x);
+void test(C<num> c) {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_index_get.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_get.dart.textual_outline.expect
new file mode 100644
index 0000000..3e84e6d
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_get.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+library test;
+
+typedef void F<T>(T x);
+
+class C<T> {
+ F<T> operator [](int i) => null;
+}
+
+F<num> test(C<num> c) {}
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_index_get.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_get.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f10da16
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_get.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+library test;
+
+F<num> test(C<num> c) {}
+
+class C<T> {
+ F<T> operator [](int i) => null;
+}
+
+main() {}
+typedef void F<T>(T x);
diff --git a/pkg/front_end/testcases/runtime_checks_new/derived_class_typed.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks_new/derived_class_typed.dart.textual_outline.expect
new file mode 100644
index 0000000..6f29a54
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/derived_class_typed.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+library test;
+
+class B<T> {
+ void f(T x) {}
+ void g({T x}) {}
+ void h<U extends T>() {}
+}
+
+class C extends B<int> {}
+
+void g1(B<num> b) {}
+void g2(C c) {}
+void test() {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/derived_class_typed.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks_new/derived_class_typed.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8dc39af
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/derived_class_typed.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+library test;
+
+class B<T> {
+ void f(T x) {}
+ void g({T x}) {}
+ void h<U extends T>() {}
+}
+
+class C extends B<int> {}
+
+void g1(B<num> b) {}
+void g2(C c) {}
+void main() {}
+void test() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_abstract_generic_covariant.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_abstract_generic_covariant.dart.textual_outline.expect
new file mode 100644
index 0000000..7cfc8c5
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_abstract_generic_covariant.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+library test;
+
+class B<T> {
+ T x;
+}
+
+class C extends B<num> {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_abstract_generic_covariant.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_abstract_generic_covariant.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7cfc8c5
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_abstract_generic_covariant.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+library test;
+
+class B<T> {
+ T x;
+}
+
+class C extends B<num> {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.textual_outline.expect
new file mode 100644
index 0000000..13b768c
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+class B {
+ covariant num x;
+}
+
+class C {
+ int x;
+}
+
+class D extends C implements B {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..13b768c
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+class B {
+ covariant num x;
+}
+
+class C {
+ int x;
+}
+
+class D extends C implements B {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/for_in_call_kinds.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks_new/for_in_call_kinds.dart.textual_outline.expect
new file mode 100644
index 0000000..f3282d1
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/for_in_call_kinds.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+library test;
+
+var topLevel;
+void set topLevelSetter(x) {}
+
+class C {
+ static var staticField;
+ static void set staticSetter(x) {}
+ var instanceField;
+ void set instanceSetter(x) {}
+ void test() {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/for_in_call_kinds.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks_new/for_in_call_kinds.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5b85754
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/for_in_call_kinds.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+class C {
+ static var staticField;
+ static void set staticSetter(x) {}
+ var instanceField;
+ void set instanceSetter(x) {}
+ void test() {}
+}
+
+main() {}
+var topLevel;
+void set topLevelSetter(x) {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..e27dd81
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.textual_outline.expect
@@ -0,0 +1,20 @@
+library test;
+
+class B<T> {
+ T x;
+ T y;
+}
+
+abstract class C<T> implements B<num> {
+ var x;
+ get y;
+ set y(value);
+}
+
+abstract class D<T> implements B<T> {
+ var x;
+ get y;
+ set y(value);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5c970ba
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.textual_outline_modelled.expect
@@ -0,0 +1,20 @@
+library test;
+
+abstract class C<T> implements B<num> {
+ get y;
+ set y(value);
+ var x;
+}
+
+abstract class D<T> implements B<T> {
+ get y;
+ set y(value);
+ var x;
+}
+
+class B<T> {
+ T x;
+ T y;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/implicit_downcast_field.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks_new/implicit_downcast_field.dart.textual_outline.expect
new file mode 100644
index 0000000..340c0be
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/implicit_downcast_field.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+library test;
+
+Object o = 1;
+bool topLevelValue = o;
+
+class C {
+ static bool staticValue = o;
+ bool instanceValue = o;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/implicit_downcast_field.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks_new/implicit_downcast_field.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3b8f20e
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/implicit_downcast_field.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+library test;
+
+Object o = 1;
+bool topLevelValue = o;
+
+class C {
+ bool instanceValue = o;
+ static bool staticValue = o;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.textual_outline.expect
new file mode 100644
index 0000000..532c570
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.textual_outline.expect
@@ -0,0 +1,27 @@
+library test;
+
+void expectTypeError(void callback()) {}
+void expect(Object value, Object expected) {}
+
+class B {
+ int get x {}
+ void set x(int value) {}
+ int get y {}
+ void set y(int value) {}
+}
+
+abstract class I<T> {
+ T get x;
+ void set x(T value);
+ Object get y;
+ void set y(covariant Object value);
+}
+
+class M {
+ int x;
+ int y;
+}
+
+class C = B with M implements I<int>;
+void test(I<Object> i) {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..89b6b10
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.textual_outline_modelled.expect
@@ -0,0 +1,26 @@
+library test;
+
+abstract class I<T> {
+ Object get y;
+ T get x;
+ void set x(T value);
+ void set y(covariant Object value);
+}
+
+class B {
+ int get x {}
+ int get y {}
+ void set x(int value) {}
+ void set y(int value) {}
+}
+
+class M {
+ int x;
+ int y;
+}
+
+void expect(Object value, Object expected) {}
+void expectTypeError(void callback()) {}
+class C = B with M implements I<int>;
+void main() {}
+void test(I<Object> i) {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.textual_outline.expect
new file mode 100644
index 0000000..7b50e59
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.textual_outline.expect
@@ -0,0 +1,29 @@
+library test;
+
+void expectTypeError(void callback()) {}
+void expect(Object value, Object expected) {}
+
+class B {
+ int get x {}
+ void set x(int value) {}
+ int get y {}
+ void set y(int value) {}
+}
+
+abstract class I<T> {
+ T get x;
+ void set x(T value);
+ Object get y;
+ void set y(covariant Object value);
+}
+
+class M {
+ int get x => 1;
+ void set x(int value) {}
+ int get y => 3;
+ void set y(int value) {}
+}
+
+class C = B with M implements I<int>;
+void test(I<Object> i) {}
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..a23006b
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.textual_outline_modelled.expect
@@ -0,0 +1,28 @@
+library test;
+
+abstract class I<T> {
+ Object get y;
+ T get x;
+ void set x(T value);
+ void set y(covariant Object value);
+}
+
+class B {
+ int get x {}
+ int get y {}
+ void set x(int value) {}
+ void set y(int value) {}
+}
+
+class M {
+ int get x => 1;
+ int get y => 3;
+ void set x(int value) {}
+ void set y(int value) {}
+}
+
+void expect(Object value, Object expected) {}
+void expectTypeError(void callback()) {}
+class C = B with M implements I<int>;
+void main() {}
+void test(I<Object> i) {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.textual_outline.expect
new file mode 100644
index 0000000..c474b44
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+library test;
+
+void expectTypeError(void callback()) {}
+void expect(Object value, Object expected) {}
+
+class B {
+ int f(int x) {}
+}
+
+abstract class I {
+ int f(covariant Object x);
+}
+
+class C extends B implements I {}
+
+void g(C c) {}
+void test(C c, I i) {}
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d49ed63
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+library test;
+
+abstract class I {
+ int f(covariant Object x);
+}
+
+class B {
+ int f(int x) {}
+}
+
+class C extends B implements I {}
+
+main() {}
+void expect(Object value, Object expected) {}
+void expectTypeError(void callback()) {}
+void g(C c) {}
+void test(C c, I i) {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.textual_outline.expect
new file mode 100644
index 0000000..83b6b0f
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+class B {
+ void f(int x, int y) {}
+}
+
+abstract class I<T> {
+ void f(T x, Object y);
+}
+
+abstract class C extends B implements I<int> {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..90a097c
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+abstract class C extends B implements I<int> {}
+
+abstract class I<T> {
+ void f(T x, Object y);
+}
+
+class B {
+ void f(int x, int y) {}
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.textual_outline.expect
new file mode 100644
index 0000000..ac08d82
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+class B<T> {
+ void f(T x, int y) {}
+}
+
+abstract class I {
+ void f(int x, Object y);
+}
+
+abstract class C extends B<int> implements I {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..22c5f69
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+abstract class C extends B<int> implements I {}
+
+abstract class I {
+ void f(int x, Object y);
+}
+
+class B<T> {
+ void f(T x, int y) {}
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.textual_outline.expect
new file mode 100644
index 0000000..d453753
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+class B {
+ void f(int x, int y) {}
+}
+
+abstract class I {
+ void f(covariant int x, Object y);
+}
+
+abstract class C extends B implements I {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f722096
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+abstract class C extends B implements I {}
+
+abstract class I {
+ void f(covariant int x, Object y);
+}
+
+class B {
+ void f(int x, int y) {}
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.textual_outline.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.textual_outline.expect
new file mode 100644
index 0000000..e101817
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+library test;
+
+class B {
+ void f(covariant int x, int y) {}
+}
+
+abstract class I {
+ void f(int x, Object y);
+}
+
+abstract class C extends B implements I {}
+
+void main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5bade16
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+library test;
+
+abstract class C extends B implements I {}
+
+abstract class I {
+ void f(int x, Object y);
+}
+
+class B {
+ void f(covariant int x, int y) {}
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.strong.expect b/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.strong.expect
index 486d1399..11b9194 100644
--- a/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.strong.expect
+++ b/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.strong.expect
@@ -16,14 +16,16 @@
// LinkedHashMap<int, bool> lhm = {};
// ^
//
-// pkg/front_end/testcases/set_literals/disambiguation_rule.dart:32:46: Error: The set literal type 'Set<dynamic>' isn't of expected type 'LinkedHashSet<int>'.
+// pkg/front_end/testcases/set_literals/disambiguation_rule.dart:32:46: Error: The set literal type 'Future<Set<dynamic>>' isn't of expected type 'Future<LinkedHashSet<int>>'.
+// - 'Future' is from 'dart:async'.
// - 'Set' is from 'dart:core'.
// - 'LinkedHashSet' is from 'dart:collection'.
// Change the type of the set literal or the context in which it is used.
// Future<LinkedHashSet<int>> lhsfun() async => {};
// ^
//
-// pkg/front_end/testcases/set_literals/disambiguation_rule.dart:33:52: Error: The map literal type 'Map<dynamic, dynamic>' isn't of expected type 'LinkedHashMap<int, bool>'.
+// pkg/front_end/testcases/set_literals/disambiguation_rule.dart:33:52: Error: The map literal type 'Future<Map<dynamic, dynamic>>' isn't of expected type 'Future<LinkedHashMap<int, bool>>'.
+// - 'Future' is from 'dart:async'.
// - 'Map' is from 'dart:core'.
// - 'LinkedHashMap' is from 'dart:collection'.
// Change the type of the map literal or the context in which it is used.
@@ -86,14 +88,16 @@
static method iterablefun() → asy::Future<core::Iterable<core::int*>*>* async
return let final core::Set<core::int*>* #t7 = col::LinkedHashSet::•<core::int*>() in #t7;
static method lhsfun() → asy::Future<col::LinkedHashSet<core::int*>*>* async
- return let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule.dart:32:46: Error: The set literal type 'Set<dynamic>' isn't of expected type 'LinkedHashSet<int>'.
+ return let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule.dart:32:46: Error: The set literal type 'Future<Set<dynamic>>' isn't of expected type 'Future<LinkedHashSet<int>>'.
+ - 'Future' is from 'dart:async'.
- 'Set' is from 'dart:core'.
- 'LinkedHashSet' is from 'dart:collection'.
Change the type of the set literal or the context in which it is used.
Future<LinkedHashSet<int>> lhsfun() async => {};
^" in let final core::Set<dynamic>* #t9 = col::LinkedHashSet::•<dynamic>() in #t9;
static method lhmfun() → asy::Future<col::LinkedHashMap<core::int*, core::bool*>*>* async
- return let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule.dart:33:52: Error: The map literal type 'Map<dynamic, dynamic>' isn't of expected type 'LinkedHashMap<int, bool>'.
+ return let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule.dart:33:52: Error: The map literal type 'Future<Map<dynamic, dynamic>>' isn't of expected type 'Future<LinkedHashMap<int, bool>>'.
+ - 'Future' is from 'dart:async'.
- 'Map' is from 'dart:core'.
- 'LinkedHashMap' is from 'dart:collection'.
Change the type of the map literal or the context in which it is used.
diff --git a/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.strong.transformed.expect b/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.strong.transformed.expect
index 7b742dc..c5bd85d 100644
--- a/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.strong.transformed.expect
@@ -16,14 +16,16 @@
// LinkedHashMap<int, bool> lhm = {};
// ^
//
-// pkg/front_end/testcases/set_literals/disambiguation_rule.dart:32:46: Error: The set literal type 'Set<dynamic>' isn't of expected type 'LinkedHashSet<int>'.
+// pkg/front_end/testcases/set_literals/disambiguation_rule.dart:32:46: Error: The set literal type 'Future<Set<dynamic>>' isn't of expected type 'Future<LinkedHashSet<int>>'.
+// - 'Future' is from 'dart:async'.
// - 'Set' is from 'dart:core'.
// - 'LinkedHashSet' is from 'dart:collection'.
// Change the type of the set literal or the context in which it is used.
// Future<LinkedHashSet<int>> lhsfun() async => {};
// ^
//
-// pkg/front_end/testcases/set_literals/disambiguation_rule.dart:33:52: Error: The map literal type 'Map<dynamic, dynamic>' isn't of expected type 'LinkedHashMap<int, bool>'.
+// pkg/front_end/testcases/set_literals/disambiguation_rule.dart:33:52: Error: The map literal type 'Future<Map<dynamic, dynamic>>' isn't of expected type 'Future<LinkedHashMap<int, bool>>'.
+// - 'Future' is from 'dart:async'.
// - 'Map' is from 'dart:core'.
// - 'LinkedHashMap' is from 'dart:collection'.
// Change the type of the map literal or the context in which it is used.
@@ -207,7 +209,8 @@
try {
#L5:
{
- :return_value = let final<BottomType> #t18 = invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule.dart:32:46: Error: The set literal type 'Set<dynamic>' isn't of expected type 'LinkedHashSet<int>'.
+ :return_value = let final<BottomType> #t18 = invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule.dart:32:46: Error: The set literal type 'Future<Set<dynamic>>' isn't of expected type 'Future<LinkedHashSet<int>>'.
+ - 'Future' is from 'dart:async'.
- 'Set' is from 'dart:core'.
- 'LinkedHashSet' is from 'dart:collection'.
Change the type of the set literal or the context in which it is used.
@@ -239,7 +242,8 @@
try {
#L6:
{
- :return_value = let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule.dart:33:52: Error: The map literal type 'Map<dynamic, dynamic>' isn't of expected type 'LinkedHashMap<int, bool>'.
+ :return_value = let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule.dart:33:52: Error: The map literal type 'Future<Map<dynamic, dynamic>>' isn't of expected type 'Future<LinkedHashMap<int, bool>>'.
+ - 'Future' is from 'dart:async'.
- 'Map' is from 'dart:core'.
- 'LinkedHashMap' is from 'dart:collection'.
Change the type of the map literal or the context in which it is used.
diff --git a/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.textual_outline.expect b/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.textual_outline.expect
new file mode 100644
index 0000000..183ae0c
--- /dev/null
+++ b/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.textual_outline.expect
@@ -0,0 +1,14 @@
+import 'dart:async' show FutureOr;
+import 'dart:collection' show LinkedHashMap, LinkedHashSet;
+
+main() async {}
+Future<Map<int, bool>> mapfun() async => {};
+Future<Set<int>> setfun() async => {};
+Future<Iterable<int>> iterablefun() async => {};
+Future<LinkedHashSet<int>> lhsfun() async => {};
+Future<LinkedHashMap<int, bool>> lhmfun() async => {};
+FutureOr<Map<int, bool>> mapfun2() => {};
+FutureOr<Set<int>> setfun2() => {};
+FutureOr<Iterable<int>> iterablefun2() => {};
+FutureOr<LinkedHashSet<int>> lhsfun2() => {};
+FutureOr<LinkedHashMap<int, bool>> lhmfun2() => {};
diff --git a/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cd5d4f6
--- /dev/null
+++ b/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.textual_outline_modelled.expect
@@ -0,0 +1,14 @@
+import 'dart:async' show FutureOr;
+import 'dart:collection' show LinkedHashMap, LinkedHashSet;
+
+Future<Iterable<int>> iterablefun() async => {};
+Future<LinkedHashMap<int, bool>> lhmfun() async => {};
+Future<LinkedHashSet<int>> lhsfun() async => {};
+Future<Map<int, bool>> mapfun() async => {};
+Future<Set<int>> setfun() async => {};
+FutureOr<Iterable<int>> iterablefun2() => {};
+FutureOr<LinkedHashMap<int, bool>> lhmfun2() => {};
+FutureOr<LinkedHashSet<int>> lhsfun2() => {};
+FutureOr<Map<int, bool>> mapfun2() => {};
+FutureOr<Set<int>> setfun2() => {};
+main() async {}
diff --git a/pkg/front_end/testcases/strong.status b/pkg/front_end/testcases/strong.status
index 907af6e..8707c0c 100644
--- a/pkg/front_end/testcases/strong.status
+++ b/pkg/front_end/testcases/strong.status
@@ -240,7 +240,7 @@
regress/issue_39035.crash: RuntimeError
regress/issue_39091_1: RuntimeError
regress/issue_39091_2: RuntimeError
-regress/utf_16_le_content.crash: Crash
+regress/utf_16_le_content.crash: RuntimeError
runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast: RuntimeError
runtime_checks_new/mixin_forwarding_stub_field: TypeCheckError
runtime_checks_new/mixin_forwarding_stub_getter: TypeCheckError
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index 41d9cf9..7ea610f 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -238,7 +238,7 @@
regress/issue_39035.crash: RuntimeError
regress/issue_39091_1: RuntimeError
regress/issue_39091_2: RuntimeError
-regress/utf_16_le_content.crash: Crash
+regress/utf_16_le_content.crash: RuntimeError
runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast: RuntimeError
runtime_checks_new/mixin_forwarding_stub_field: TypeCheckError
runtime_checks_new/mixin_forwarding_stub_setter: TypeCheckError
diff --git a/pkg/front_end/testcases/textual_outline.status b/pkg/front_end/testcases/textual_outline.status
new file mode 100644
index 0000000..bbf696b
--- /dev/null
+++ b/pkg/front_end/testcases/textual_outline.status
@@ -0,0 +1,208 @@
+# Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE.md file.
+
+# Status file for the textual_outline_suite.dart test suite. This is testing
+# the textual outline used for better incremental compilation.
+
+general/error_recovery/issue_38415.crash: EmptyOutput
+general/error_recovery/issue_39024.crash: EmptyOutput
+general/error_recovery/issue_39058.crash: EmptyOutput
+rasta/bad_interpolation: EmptyOutput
+rasta/issue_000035: EmptyOutput
+rasta/issue_000035a: EmptyOutput
+rasta/issue_000045: EmptyOutput
+regress/issue_29976: EmptyOutput
+regress/issue_29982: EmptyOutput
+regress/issue_29985: EmptyOutput
+regress/issue_35900: EmptyOutput
+regress/issue_39035.crash: EmptyOutput
+regress/issue_39091_2: EmptyOutput
+regress/utf_16_le_content.crash: EmptyOutput
+
+rasta/issue_000032: FormatterCrash
+regress/issue_34614: FormatterCrash
+extensions/ambiguous: FormatterCrash
+extensions/annotations: FormatterCrash
+extensions/builtin_identifiers: FormatterCrash
+extensions/call_methods: FormatterCrash
+extensions/check_bounds: FormatterCrash
+extensions/compounds: FormatterCrash
+extensions/conflict_with_object: FormatterCrash
+extensions/conflicts: FormatterCrash
+extensions/default_values: FormatterCrash
+extensions/direct_instance_access: FormatterCrash
+extensions/direct_static_access: FormatterCrash
+extensions/dynamic_invoke: FormatterCrash
+extensions/explicit_extension_access: FormatterCrash
+extensions/explicit_extension_inference: FormatterCrash
+extensions/explicit_generic_extension_access: FormatterCrash
+extensions/explicit_invalid_access: FormatterCrash
+extensions/explicit_this: FormatterCrash
+extensions/extension_call: FormatterCrash
+extensions/extension_constructor: FormatterCrash
+extensions/extension_field_with_type_parameter_usage: FormatterCrash
+extensions/extension_methods: FormatterCrash
+extensions/extension_setter_error: FormatterCrash
+extensions/extension_setter: FormatterCrash
+extensions/generic_function_in_generic_extension: FormatterCrash
+extensions/getter_setter_conflict: FormatterCrash
+extensions/if_null: FormatterCrash
+extensions/implicit_extension_inference: FormatterCrash
+extensions/implicit_this: FormatterCrash
+extensions/index: FormatterCrash
+extensions/instance_access_of_static: FormatterCrash
+extensions/instance_access: FormatterCrash
+extensions/instance_members: FormatterCrash
+extensions/instance_tearoff: FormatterCrash
+extensions/internal_resolution: FormatterCrash
+extensions/invalid_explicit_access: FormatterCrash
+extensions/invalid_explicit_static_access: FormatterCrash
+extensions/issue38600: FormatterCrash
+extensions/issue38712: FormatterCrash
+extensions/issue38713: FormatterCrash
+extensions/issue38745: FormatterCrash
+extensions/issue38755: FormatterCrash
+extensions/issue38915: FormatterCrash
+extensions/issue39527: FormatterCrash
+extensions/issue39889: FormatterCrash
+extensions/issue40596: FormatterCrash
+extensions/issue40713: FormatterCrash
+extensions/issue40816: FormatterCrash
+extensions/missing_toplevel: FormatterCrash
+extensions/nested_on_types: FormatterCrash
+extensions/null_aware: FormatterCrash
+extensions/on_function_type: FormatterCrash
+extensions/on_type_inference: FormatterCrash
+extensions/on_type_variable_inference: FormatterCrash
+extensions/operators: FormatterCrash
+extensions/other_kinds: FormatterCrash
+extensions/static_access_of_instance: FormatterCrash
+extensions/static_access: FormatterCrash
+extensions/tear_offs: FormatterCrash
+extensions/type_variables: FormatterCrash
+extensions/unnamed_extensions: FormatterCrash
+extensions/use_this: FormatterCrash
+general_nnbd_opt_out/annotation_eof: FormatterCrash
+general_nnbd_opt_out/bad_setter_abstract: FormatterCrash
+general_nnbd_opt_out/bug31124: FormatterCrash
+general_nnbd_opt_out/clone_function_type: FormatterCrash
+general_nnbd_opt_out/constructor_initializer_invalid: FormatterCrash
+general_nnbd_opt_out/duplicated_declarations: FormatterCrash
+general_nnbd_opt_out/function_type_default_value: FormatterCrash
+general_nnbd_opt_out/incomplete_field_formal_parameter: FormatterCrash
+general_nnbd_opt_out/many_errors: FormatterCrash
+general_nnbd_opt_out/var_as_type_name: FormatterCrash
+general/annotation_eof: FormatterCrash
+general/bad_setter_abstract: FormatterCrash
+general/bug31124: FormatterCrash
+general/clone_function_type: FormatterCrash
+general/constructor_initializer_invalid: FormatterCrash
+general/duplicated_declarations: FormatterCrash
+general/error_recovery/constructor_recovery_bad_name_general.crash: FormatterCrash
+general/error_recovery/constructor_recovery_bad_name_get.crash: FormatterCrash
+general/error_recovery/constructor_recovery_bad_name_return_type.crash: FormatterCrash
+general/error_recovery/constructor_recovery_bad_name_set.crash: FormatterCrash
+general/error_recovery/constructor_recovery_get: FormatterCrash
+general/error_recovery/constructor_recovery_operator.crash: FormatterCrash
+general/error_recovery/constructor_recovery_return_type: FormatterCrash
+general/error_recovery/constructor_recovery_set: FormatterCrash
+general/error_recovery/issue_39033.crash: FormatterCrash
+general/error_recovery/issue_39058_prime.crash: FormatterCrash
+general/error_recovery/issue_39202.crash: FormatterCrash
+general/error_recovery/issue_39230.crash: FormatterCrash
+general/error_recovery/issue_39958_01: FormatterCrash
+general/function_type_default_value: FormatterCrash
+general/incomplete_field_formal_parameter: FormatterCrash
+general/invalid_operator: FormatterCrash
+general/invalid_operator2: FormatterCrash
+general/issue40242: FormatterCrash
+general/many_errors: FormatterCrash
+general/type_parameter_usage_in_static_method_in_extension: FormatterCrash
+general/type_parameters_on_void: FormatterCrash
+general/var_as_type_name: FormatterCrash
+general/well_boundness_checks_in_outline: FormatterCrash
+inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr1: FormatterCrash
+inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr1: FormatterCrash
+late_lowering/infer_late_field_type: FormatterCrash
+late_lowering/initializer_rewrite: FormatterCrash
+late_lowering/instance_field_with_initializer: FormatterCrash
+late_lowering/instance_field_without_initializer: FormatterCrash
+late_lowering/instance_final_field_without_initializer: FormatterCrash
+late_lowering/instance_nullable_field_with_initializer: FormatterCrash
+late_lowering/instance_nullable_field_without_initializer: FormatterCrash
+late_lowering/instance_nullable_final_field_without_initializer: FormatterCrash
+late_lowering/issue40373: FormatterCrash
+late_lowering/issue40373b: FormatterCrash
+late_lowering/issue40805: FormatterCrash
+late_lowering/issue41436b: FormatterCrash
+late_lowering/late_field_inference: FormatterCrash
+late_lowering/late_field_with_initializer: FormatterCrash
+late_lowering/late_field_without_initializer: FormatterCrash
+late_lowering/late_final_field_with_initializer: FormatterCrash
+late_lowering/late_final_field_without_initializer: FormatterCrash
+late_lowering/late_final_nullable_field_with_initializer: FormatterCrash
+late_lowering/late_final_nullable_field_without_initializer: FormatterCrash
+late_lowering/late_future_or: FormatterCrash
+late_lowering/late_nullable_field_with_initializer: FormatterCrash
+late_lowering/late_nullable_field_without_initializer: FormatterCrash
+late_lowering/later: FormatterCrash
+late_lowering/override_getter_setter: FormatterCrash
+late_lowering/override: FormatterCrash
+late_lowering/uninitialized_non_nullable_late_fields: FormatterCrash
+nnbd/forbidden_supers: FormatterCrash
+nnbd/infer_if_null: FormatterCrash
+nnbd/inheritance_from_opt_in: FormatterCrash
+nnbd/issue40805: FormatterCrash
+nnbd/issue41349: FormatterCrash
+nnbd/issue41597: FormatterCrash
+nnbd/late: FormatterCrash
+nnbd/later: FormatterCrash
+nnbd/no_null_shorting_explicit_extension: FormatterCrash
+nnbd/no_null_shorting_extension: FormatterCrash
+nnbd/non_nullable_field_initialization: FormatterCrash
+nnbd/null_shorting_cascade: FormatterCrash
+nnbd/null_shorting_explicit_extension: FormatterCrash
+nnbd/null_shorting_extension: FormatterCrash
+nnbd/null_shorting_index: FormatterCrash
+nnbd/opt_out: FormatterCrash
+nnbd/potentially_non_nullable_field: FormatterCrash
+nnbd/potentially_nullable_access: FormatterCrash
+nnbd/strictly_non_nullable_warnings: FormatterCrash
+nnbd/uninitialized_non_nullable_late_fields: FormatterCrash
+nonfunction_type_aliases/issue41501: FormatterCrash
+rasta/bad_redirection: FormatterCrash
+rasta/issue_000034: FormatterCrash
+rasta/issue_000036: FormatterCrash
+rasta/issue_000044: FormatterCrash
+rasta/issue_000046: FormatterCrash
+rasta/issue_000047: FormatterCrash
+rasta/malformed_const_constructor: FormatterCrash
+rasta/mandatory_parameter_initializer: FormatterCrash
+regress/issue_29942: FormatterCrash
+regress/issue_29944: FormatterCrash
+regress/issue_29983: FormatterCrash
+regress/issue_29986: FormatterCrash
+regress/issue_30834: FormatterCrash
+regress/issue_30981: FormatterCrash
+regress/issue_30994: FormatterCrash
+regress/issue_31155: FormatterCrash
+regress/issue_31171: FormatterCrash
+regress/issue_31183: FormatterCrash
+regress/issue_31188: FormatterCrash
+regress/issue_31192: FormatterCrash
+regress/issue_31198: FormatterCrash
+regress/issue_34225: FormatterCrash
+regress/issue_34563: FormatterCrash
+regress/issue_34610: FormatterCrash
+regress/issue_34850: FormatterCrash
+regress/issue_35151: FormatterCrash
+regress/issue_36400: FormatterCrash
+regress/issue_37285: FormatterCrash
+regress/issue_39091_1: FormatterCrash
+regress/issue_41265.crash: Crash
+triple_shift/invalid_operator: FormatterCrash
+variance/class_type_parameter_modifier: FormatterCrash
+variance/generic_covariance_sound_variance: FormatterCrash
+variance/mixin_type_parameter_modifier: FormatterCrash
+variance/unconstrained_inference: FormatterCrash
diff --git a/pkg/front_end/testcases/top_level_variance_test.dart.textual_outline.expect b/pkg/front_end/testcases/top_level_variance_test.dart.textual_outline.expect
new file mode 100644
index 0000000..7636a6d
--- /dev/null
+++ b/pkg/front_end/testcases/top_level_variance_test.dart.textual_outline.expect
@@ -0,0 +1,23 @@
+typedef F<X> = void Function<Y extends X>();
+F<X> toF<X>(X x) => null;
+typedef Fcov<X> = X Function();
+typedef Fcon<X> = Function(X);
+typedef Finv<X> = X Function(X);
+typedef FcovBound<X extends num> = X Function();
+typedef FconBound<X extends num> = Function(X);
+typedef FinvBound<X extends num> = X Function(X);
+
+class A<X> {}
+
+typedef FcovCyclicBound<X extends A<X>> = X Function();
+typedef FconCyclicBound<X extends A<X>> = Function(X);
+typedef FinvCyclicBound<X extends A<X>> = X Function(X);
+typedef FcovCyclicCoBound<X extends Function(X)> = X Function();
+typedef FconCyclicCoBound<X extends Function(X)> = Function(X);
+typedef FinvCyclicCoBound<X extends Function(X)> = X Function(X);
+
+class B<X> {}
+
+void testTopLevel() {}
+void testNested() {}
+main() {}
diff --git a/pkg/front_end/testcases/top_level_variance_test.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/top_level_variance_test.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d694da5
--- /dev/null
+++ b/pkg/front_end/testcases/top_level_variance_test.dart.textual_outline_modelled.expect
@@ -0,0 +1,22 @@
+F<X> toF<X>(X x) => null;
+
+class A<X> {}
+
+class B<X> {}
+
+main() {}
+typedef F<X> = void Function<Y extends X>();
+typedef Fcon<X> = Function(X);
+typedef FconBound<X extends num> = Function(X);
+typedef FconCyclicBound<X extends A<X>> = Function(X);
+typedef FconCyclicCoBound<X extends Function(X)> = Function(X);
+typedef Fcov<X> = X Function();
+typedef FcovBound<X extends num> = X Function();
+typedef FcovCyclicBound<X extends A<X>> = X Function();
+typedef FcovCyclicCoBound<X extends Function(X)> = X Function();
+typedef Finv<X> = X Function(X);
+typedef FinvBound<X extends num> = X Function(X);
+typedef FinvCyclicBound<X extends A<X>> = X Function(X);
+typedef FinvCyclicCoBound<X extends Function(X)> = X Function(X);
+void testNested() {}
+void testTopLevel() {}
diff --git a/pkg/front_end/testcases/triple_shift/invalid_operator.dart.textual_outline.expect b/pkg/front_end/testcases/triple_shift/invalid_operator.dart.textual_outline.expect
new file mode 100644
index 0000000..708b749
--- /dev/null
+++ b/pkg/front_end/testcases/triple_shift/invalid_operator.dart.textual_outline.expect
@@ -0,0 +1,29 @@
+class Operators1 {
+ operator >>( ){ }
+ operator>() => true;
+}
+class Operators2 {
+ operator >>( ){ }
+ operator>(a, b) => true;
+}
+class Operators3 {
+ operator >>( ){ }
+ operator>([a]) => true;
+}
+class Operators4 {
+ operator >>( ){ }
+ operator>({a}) => true;
+}
+class Operators5 {
+ operator >>( ){ }
+ operator>(a, [b]) => true;
+}
+class Operators6 {
+ operator >>( ){ }
+ operator>(a, {b}) => true;
+}
+class Operators7 {
+ operator >>( ){ }
+ operator><T>(a) => true;
+}
+main() { }
diff --git a/pkg/front_end/testcases/unified_collections/mixed_entries.dart.textual_outline.expect b/pkg/front_end/testcases/unified_collections/mixed_entries.dart.textual_outline.expect
new file mode 100644
index 0000000..480a19e
--- /dev/null
+++ b/pkg/front_end/testcases/unified_collections/mixed_entries.dart.textual_outline.expect
@@ -0,0 +1,109 @@
+bool b = false;
+var list = [];
+var map0 = {};
+var map1 = {if (b) 0: 1 else ...map0};
+var map2 = {if (b) ...map0 else 0: 1};
+var map3 = {if (b) ...map0 else ...map0};
+var map4 = {
+ if (b)
+ 0: 1
+ else
+ for (var a in list) a: 1
+};
+var map5 = {
+ if (b)
+ for (var a in list) a: 1
+ else
+ 0: 1
+};
+var map6 = {
+ if (b)
+ 0: 1
+ else
+ for (var a in list) ...{a: 1}
+};
+var map7 = {
+ if (b)
+ for (var a in list) ...{a: 1}
+ else
+ 0: 1
+};
+var map8 = {
+ if (b)
+ 0: 1
+ else
+ for (var i = 0; i < list.length; i++) list[i]: 1
+};
+var map9 = {
+ if (b)
+ for (var i = 0; i < list.length; i++) list[i]: 1
+ else
+ 0: 1
+};
+var map10 = {
+ if (b)
+ 0: 1
+ else
+ for (var i = 0; i < list.length; i++) ...{list[i]: 1}
+};
+var map11 = {
+ if (b)
+ for (var i = 0; i < list.length; i++) ...{list[i]: 1}
+ else
+ 0: 1
+};
+var map12 = {
+ if (b) 0: 1 else if (b) ...{0: 1}
+};
+var error4 = {
+ if (b)
+ 0: 1
+ else
+ for (var a in list) a
+};
+var error5 = {
+ if (b)
+ for (var a in list) a
+ else
+ 0: 1
+};
+var error6 = {
+ if (b)
+ 0: 1
+ else
+ for (var a in list) ...{a}
+};
+var error7 = {
+ if (b)
+ for (var a in list) ...{a}
+ else
+ 0: 1
+};
+var error8 = {
+ if (b)
+ 0: 1
+ else
+ for (var i = 0; i < list.length; i++) list[i]
+};
+var error9 = {
+ if (b)
+ for (var i = 0; i < list.length; i++) list[i]
+ else
+ 0: 1
+};
+var error10 = {
+ if (b)
+ 0: 1
+ else
+ for (var i = 0; i < list.length; i++) ...{list[i]}
+};
+var error11 = {
+ if (b)
+ for (var i = 0; i < list.length; i++) ...{list[i]}
+ else
+ 0: 1
+};
+var error12 = {
+ if (b) 0: 1 else if (b) ...{0}
+};
+main() {}
diff --git a/pkg/front_end/testcases/unified_collections/mixed_entries.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/unified_collections/mixed_entries.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1843b5c
--- /dev/null
+++ b/pkg/front_end/testcases/unified_collections/mixed_entries.dart.textual_outline_modelled.expect
@@ -0,0 +1,109 @@
+bool b = false;
+main() {}
+var error10 = {
+ if (b)
+ 0: 1
+ else
+ for (var i = 0; i < list.length; i++) ...{list[i]}
+};
+var error11 = {
+ if (b)
+ for (var i = 0; i < list.length; i++) ...{list[i]}
+ else
+ 0: 1
+};
+var error12 = {
+ if (b) 0: 1 else if (b) ...{0}
+};
+var error4 = {
+ if (b)
+ 0: 1
+ else
+ for (var a in list) a
+};
+var error5 = {
+ if (b)
+ for (var a in list) a
+ else
+ 0: 1
+};
+var error6 = {
+ if (b)
+ 0: 1
+ else
+ for (var a in list) ...{a}
+};
+var error7 = {
+ if (b)
+ for (var a in list) ...{a}
+ else
+ 0: 1
+};
+var error8 = {
+ if (b)
+ 0: 1
+ else
+ for (var i = 0; i < list.length; i++) list[i]
+};
+var error9 = {
+ if (b)
+ for (var i = 0; i < list.length; i++) list[i]
+ else
+ 0: 1
+};
+var list = [];
+var map0 = {};
+var map1 = {if (b) 0: 1 else ...map0};
+var map10 = {
+ if (b)
+ 0: 1
+ else
+ for (var i = 0; i < list.length; i++) ...{list[i]: 1}
+};
+var map11 = {
+ if (b)
+ for (var i = 0; i < list.length; i++) ...{list[i]: 1}
+ else
+ 0: 1
+};
+var map12 = {
+ if (b) 0: 1 else if (b) ...{0: 1}
+};
+var map2 = {if (b) ...map0 else 0: 1};
+var map3 = {if (b) ...map0 else ...map0};
+var map4 = {
+ if (b)
+ 0: 1
+ else
+ for (var a in list) a: 1
+};
+var map5 = {
+ if (b)
+ for (var a in list) a: 1
+ else
+ 0: 1
+};
+var map6 = {
+ if (b)
+ 0: 1
+ else
+ for (var a in list) ...{a: 1}
+};
+var map7 = {
+ if (b)
+ for (var a in list) ...{a: 1}
+ else
+ 0: 1
+};
+var map8 = {
+ if (b)
+ 0: 1
+ else
+ for (var i = 0; i < list.length; i++) list[i]: 1
+};
+var map9 = {
+ if (b)
+ for (var i = 0; i < list.length; i++) list[i]: 1
+ else
+ 0: 1
+};
diff --git a/pkg/front_end/testcases/unified_collections/string_concatenation.dart.textual_outline.expect b/pkg/front_end/testcases/unified_collections/string_concatenation.dart.textual_outline.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/unified_collections/string_concatenation.dart.textual_outline.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/unified_collections/string_concatenation.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/unified_collections/string_concatenation.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bae895a
--- /dev/null
+++ b/pkg/front_end/testcases/unified_collections/string_concatenation.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+main() {}
diff --git a/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart.textual_outline.expect b/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart.textual_outline.expect
new file mode 100644
index 0000000..f9fc129
--- /dev/null
+++ b/pkg/front_end/testcases/variance/class_type_parameter_modifier.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+class A<out X, in Y, inout Z> {
+}
+main() { }
diff --git a/pkg/front_end/testcases/variance/generic_covariance_sound_variance.dart.textual_outline.expect b/pkg/front_end/testcases/variance/generic_covariance_sound_variance.dart.textual_outline.expect
new file mode 100644
index 0000000..d888571
--- /dev/null
+++ b/pkg/front_end/testcases/variance/generic_covariance_sound_variance.dart.textual_outline.expect
@@ -0,0 +1,42 @@
+typedef ContraFunction<T> = void Function(T);
+typedef InvFunction<T> = T Function(T);
+class Contravariant<in T> {
+}
+class Invariant<inout T> {
+}
+class A<in T, out U, V> {
+ final void Function(T) field = null;
+ void method(T t, void Function(U) u, V v) { }
+ void method2(T x, [T y]) { }
+ void set x(T t) { }
+ Map<U, Contravariant<V>> get mapContra => new Map<U, Contravariant<V>>();
+ Map<U, ContraFunction<V>> get mapContraFn => new Map<U, ContraFunction<V>>();
+ Map<U, Invariant<V>> get mapInv => new Map<U, Invariant<V>>();
+ Map<U, InvFunction<V>> get mapInvFn => new Map<U, InvFunction<V>>();
+}
+class B<inout T> {
+ T x;
+ T method(T x) => x;
+ void set y(T x) { }
+}
+class C<in T> {
+ final void Function(T) field = null;
+ void method(T x, [T y]) { }
+ void set x(T t) { }
+}
+abstract class D<T> {
+ int method(T x);
+}
+class E<inout T> {
+ final void Function(T) f;
+ E(this.f);
+ int method(T x) { }
+}
+class F<inout T> extends E<T> implements D<T> {
+ F(void Function(T) f) : super(f);
+}
+class NoSuchMethod<inout T> implements B<T> {
+ noSuchMethod(_) => 3;
+}
+main() { }
+expect(expected, actual) { }
diff --git a/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart.textual_outline.expect b/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart.textual_outline.expect
new file mode 100644
index 0000000..2a9a258
--- /dev/null
+++ b/pkg/front_end/testcases/variance/mixin_type_parameter_modifier.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+class A {
+}
+mixin B<inout X, out Y, in Z> on A {
+}
+main() { }
diff --git a/pkg/front_end/testcases/variance/unconstrained_inference.dart.textual_outline.expect b/pkg/front_end/testcases/variance/unconstrained_inference.dart.textual_outline.expect
new file mode 100644
index 0000000..000a126
--- /dev/null
+++ b/pkg/front_end/testcases/variance/unconstrained_inference.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class Covariant<out T> {
+}
+class Contravariant<in T> {
+}
+class Invariant<inout T> {
+}
+void covariantListInfer<T>(Covariant<List<T>> x) { }
+void contravariantListInfer<T>(Contravariant<List<T>> x) { }
+void invariantListInfer<T>(Invariant<List<T>> x) { }
+main() { }
diff --git a/pkg/front_end/testing.json b/pkg/front_end/testing.json
index af436d3..a9488bf 100644
--- a/pkg/front_end/testing.json
+++ b/pkg/front_end/testing.json
@@ -43,6 +43,24 @@
]
},
{
+ "name": "textual_outline",
+ "kind": "Chain",
+ "source": "test/fasta/textual_outline_suite.dart",
+ "path": "testcases/",
+ "status": "testcases/textual_outline.status",
+ "pattern": [
+ "\\.dart$",
+ "\\.crash_dart$"
+ ],
+ "exclude": [
+ "/testcases/.*_part[0-9]*\\.dart$",
+ "/testcases/.*_lib[0-9]*\\.dart$",
+ "/testcases/dartino/",
+ "/testcases/shaker/",
+ "/testcases/expression/"
+ ]
+ },
+ {
"name": "outline",
"kind": "Chain",
"source": "test/fasta/outline_suite.dart",
diff --git a/pkg/kernel/lib/text/text_serialization_verifier.dart b/pkg/kernel/lib/text/text_serialization_verifier.dart
index 7d60bb7..44e9240 100644
--- a/pkg/kernel/lib/text/text_serialization_verifier.dart
+++ b/pkg/kernel/lib/text/text_serialization_verifier.dart
@@ -54,8 +54,8 @@
: super(uri, offset);
}
-class VerificationStatus {
- final VerificationStatus parent;
+class VerificationState {
+ final VerificationState parent;
final Node node;
@@ -71,7 +71,7 @@
final Set<TypeParameter> usedTypeParameters =
new Set<TypeParameter>.identity();
- VerificationStatus(this.parent, this.node);
+ VerificationState(this.parent, this.node);
bool get isRoot => parent == null;
@@ -94,9 +94,9 @@
!isRoot && parent.isTypeParameterDeclared(node);
}
- void handleChild(VerificationStatus childStatus) {
+ void handleChild(VerificationState childState) {
allChildrenAreSupported =
- allChildrenAreSupported && childStatus.isFullySupported;
+ allChildrenAreSupported && childState.isFullySupported;
}
void handleDeclarations() {
@@ -249,31 +249,33 @@
final List<TextSerializationVerificationFailure> failures =
<TextSerializationVerificationFailure>[];
+ /// List of status for all round-trip serialization attempts.
+ final List<RoundTripStatus> status = <RoundTripStatus>[];
+
final CanonicalName root;
Uri lastSeenUri = noUri;
int lastSeenOffset = noOffset;
- VerificationStatus _statusStackTop;
+ VerificationState _stateStackTop;
TextSerializationVerifier({CanonicalName root})
: root = root ?? new CanonicalName.root() {
initializeSerializers();
}
- VerificationStatus get currentStatus => _statusStackTop;
+ VerificationState get currentState => _stateStackTop;
- void pushStatusFor(Node node) {
- _statusStackTop = new VerificationStatus(_statusStackTop, node);
+ void pushStateFor(Node node) {
+ _stateStackTop = new VerificationState(_stateStackTop, node);
}
- void dropStatus() {
- if (_statusStackTop == null) {
- throw new StateError(
- "Attempting to remove a status from an empty status stack.");
+ void dropState() {
+ if (_stateStackTop == null) {
+ throw new StateError("Attempting to remove a state from an empty stack.");
}
- _statusStackTop = _statusStackTop.parent;
+ _stateStackTop = _stateStackTop.parent;
}
void verify(Node node) => node.accept(this);
@@ -286,21 +288,21 @@
void enterNode(node) {
storeLastSeenUriAndOffset(node);
- pushStatusFor(node);
- currentStatus.handleDeclarations();
+ pushStateFor(node);
+ currentState.handleDeclarations();
}
void exitNode(node) {
- if (!identical(node, currentStatus.node)) {
+ if (!identical(node, currentState.node)) {
throw new StateError("Trying to remove node '${node}' from the stack, "
- "while another node '${currentStatus.node}' is on the top of it.");
+ "while another node '${currentState.node}' is on the top of it.");
}
- List<Node> roundTripReadyNodes = currentStatus.takeRoundTripReadyNodes();
+ List<Node> roundTripReadyNodes = currentState.takeRoundTripReadyNodes();
for (Node node in roundTripReadyNodes) {
- makeRoundTripDispatch(node);
+ status.add(makeRoundTripDispatch(node));
}
- currentStatus.mergeToParent();
- dropStatus();
+ currentState.mergeToParent();
+ dropState();
}
void storeLastSeenUriAndOffset(Node node) {
@@ -374,7 +376,7 @@
// The error is reported elsewhere for the case of null.
if (deserialized == null) {
- return new RoundTripStatus(false, initial);
+ return new RoundTripStatus(false, node, initial);
}
String serialized =
@@ -383,15 +385,82 @@
if (initial != serialized) {
failures.add(new TextRoundTripFailure(
initial, serialized, lastSeenUri, lastSeenOffset));
- return new RoundTripStatus(false, initial);
+ return new RoundTripStatus(false, node, initial);
}
- return new RoundTripStatus(true, initial);
+ return new RoundTripStatus(true, node, initial);
}
}
-class RoundTripStatus {
+class RoundTripStatus implements Comparable<RoundTripStatus> {
final bool successful;
+ final Node node;
final String serialized;
- RoundTripStatus(this.successful, this.serialized);
+ RoundTripStatus(this.successful, this.node, this.serialized)
+ : assert(successful != null),
+ assert(node != null),
+ assert(serialized != null);
+
+ void printOn(StringBuffer sb) {
+ sb.writeln(
+ ";; -----------------------------------------------------------------------------");
+ sb.writeln("Status: ${successful ? "OK" : "ERROR"}");
+ sb.writeln("Node type: ${node.runtimeType}");
+ sb.writeln("Node: ${node.leakingDebugToString()}");
+ if (node is TreeNode) {
+ TreeNode treeNode = node;
+ sb.writeln("Parent type: ${treeNode.parent.runtimeType}");
+ sb.writeln("Parent: ${treeNode.parent.leakingDebugToString()}");
+ }
+ sb.writeln("Serialized: ${serialized}");
+ sb.writeln();
+ }
+
+ int compareTo(RoundTripStatus other) {
+ if (node is TreeNode && other.node is TreeNode) {
+ TreeNode thisNode = this.node;
+ TreeNode otherNode = other.node;
+ Uri thisUri = thisNode.location?.file;
+ Uri otherUri = otherNode.location?.file;
+ int thisOffset = thisNode.fileOffset;
+ int otherOffset = otherNode.fileOffset;
+
+ int compareUri;
+ if (thisUri == null && otherUri == null) {
+ compareUri = 0;
+ } else if (thisUri == null) {
+ compareUri = 1;
+ } else if (otherUri == null) {
+ return -1;
+ } else {
+ assert(thisUri != null && otherUri != null);
+ compareUri = thisUri.toString().compareTo(otherUri.toString());
+ }
+ if (compareUri != 0) return compareUri;
+
+ int compareOffset;
+ if (thisOffset == null && otherOffset == null) {
+ compareOffset = 0;
+ } else if (thisOffset == null) {
+ compareOffset = 1;
+ } else if (otherOffset == null) {
+ compareOffset = -1;
+ } else {
+ compareOffset = thisOffset = otherOffset;
+ }
+ if (compareOffset != 0) return compareOffset;
+
+ if (!successful && other.successful) {
+ return -1;
+ } else if (successful && !other.successful) {
+ return 1;
+ }
+
+ return serialized.compareTo(other.serialized);
+ } else if (node is TreeNode) {
+ return -1;
+ } else {
+ return 1;
+ }
+ }
}
diff --git a/pkg/meta/pubspec.yaml b/pkg/meta/pubspec.yaml
index 3e5ecaf..4ca8152 100644
--- a/pkg/meta/pubspec.yaml
+++ b/pkg/meta/pubspec.yaml
@@ -7,4 +7,4 @@
semantic information about the program being annotated. These annotations are
intended to be used by tools to provide a better user experience.
environment:
- sdk: '>=1.12.0 <3.0.0'
+ sdk: '>=2.9.0 <3.0.0'
diff --git a/pkg/nnbd_migration/lib/instrumentation.dart b/pkg/nnbd_migration/lib/instrumentation.dart
index 06b285b..e8a6404 100644
--- a/pkg/nnbd_migration/lib/instrumentation.dart
+++ b/pkg/nnbd_migration/lib/instrumentation.dart
@@ -222,6 +222,7 @@
enum EdgeOriginKind {
alreadyMigratedType,
alwaysNullableType,
+ argumentErrorCheckNotNull,
compoundAssignment,
// See [DummyOrigin].
dummy,
@@ -241,8 +242,8 @@
instantiateToBounds,
isCheckComponentType,
isCheckMainType,
- literal,
listLengthConstructor,
+ literal,
namedParameterNotSupplied,
nonNullableBoolType,
nonNullableObjectSuperclass,
@@ -251,6 +252,7 @@
nullabilityComment,
optionalFormalParameter,
parameterInheritance,
+ quiverCheckNotNull,
returnTypeInheritance,
stackTraceTypeOrigin,
thisOrSuper,
diff --git a/pkg/nnbd_migration/lib/migration_cli.dart b/pkg/nnbd_migration/lib/migration_cli.dart
index d8d0350..41c3f0f 100644
--- a/pkg/nnbd_migration/lib/migration_cli.dart
+++ b/pkg/nnbd_migration/lib/migration_cli.dart
@@ -10,12 +10,16 @@
import 'package:analyzer/dart/analysis/analysis_context.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/session.dart';
+import 'package:analyzer/diagnostic/diagnostic.dart';
+import 'package:analyzer/error/error.dart';
import 'package:analyzer/file_system/file_system.dart' show ResourceProvider;
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart';
+import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/util/sdk.dart';
-import 'package:analyzer_plugin/protocol/protocol_common.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart'
+ hide AnalysisError;
import 'package:args/args.dart';
import 'package:cli_util/cli_logging.dart';
import 'package:meta/meta.dart';
@@ -27,12 +31,17 @@
return count == 1 ? single : (multiple ?? '${single}s');
}
+String _removePeriod(String value) {
+ return value.endsWith('.') ? value.substring(0, value.length - 1) : value;
+}
+
/// Data structure recording command-line options for the migration tool that
/// have been passed in by the client.
@visibleForTesting
class CommandLineOptions {
static const applyChangesFlag = 'apply-changes';
static const helpFlag = 'help';
+ static const ignoreErrorsFlag = 'ignore-errors';
static const previewPortOption = 'preview-port';
static const sdkPathOption = 'sdk-path';
static const verboseFlag = 'verbose';
@@ -42,6 +51,8 @@
final String directory;
+ final bool ignoreErrors;
+
final int previewPort;
final String sdkPath;
@@ -51,6 +62,7 @@
CommandLineOptions(
{@required this.applyChanges,
@required this.directory,
+ @required this.ignoreErrors,
@required this.previewPort,
@required this.sdkPath,
@required this.webPreview});
@@ -85,6 +97,10 @@
/// if there is still more work to do.
int exitCode;
+ final Map<String, List<AnalysisError>> fileErrors = {};
+
+ final Map<String, LineInfo> lineInfo = {};
+
MigrationCli(
{@required this.binaryName,
@visibleForTesting this.loggerFactory = _defaultLoggerFactory,
@@ -148,6 +164,7 @@
options = CommandLineOptions(
applyChanges: applyChanges,
directory: migratePath,
+ ignoreErrors: argResults[CommandLineOptions.ignoreErrorsFlag] as bool,
previewPort: previewPort,
sdkPath: argResults[CommandLineOptions.sdkPathOption] as String ??
defaultSdkPathOverride ??
@@ -183,8 +200,6 @@
logger.stdout('Migrating ${options.directory}');
logger.stdout('');
- // TODO(paulberry): analyze project and report about any errors found
-
List<String> previewUrls;
NonNullableFix nonNullableFix;
_DartFixListener dartFixListener;
@@ -195,7 +210,7 @@
resourceProvider: resourceProvider,
sdkPath: options.sdkPath);
var context = contextCollection.contexts.single;
- var fixCodeProcessor = _FixCodeProcessor(context);
+ var fixCodeProcessor = _FixCodeProcessor(context, this);
dartFixListener = _DartFixListener(
_DriverProvider(resourceProvider, context.currentSession));
nonNullableFix = NonNullableFix(dartFixListener,
@@ -203,8 +218,17 @@
preferredPort: options.previewPort,
enablePreview: options.webPreview);
fixCodeProcessor.registerCodeTask(nonNullableFix);
- previewUrls = await fixCodeProcessor.run();
+ try {
+ await fixCodeProcessor.runFirstPhase();
+ _checkForErrors();
+ } on StateError catch (e) {
+ logger.stdout(e.toString());
+ exitCode = 1;
+ }
+ if (exitCode != null) return;
+ previewUrls = await fixCodeProcessor.runLaterPhases();
});
+ if (exitCode != null) return;
if (options.applyChanges) {
logger.stdout(ansi.emphasized('Applying changes:'));
@@ -294,6 +318,46 @@
}
}
+ void _checkForErrors() {
+ if (fileErrors.isEmpty) {
+ logger.stdout('No analysis issues found.');
+ } else {
+ logger.stdout('');
+
+ int issueCount =
+ fileErrors.values.map((list) => list.length).reduce((a, b) => a + b);
+ logger.stdout(
+ '$issueCount analysis ${_pluralize(issueCount, 'issue')} found:');
+ List<AnalysisError> allErrors = fileErrors.values
+ .fold(<AnalysisError>[], (list, element) => list..addAll(element));
+ _displayIssues(logger, options.directory, allErrors, lineInfo);
+ var importErrorCount = allErrors.where(_isUriError).length;
+
+ logger.stdout('');
+ logger.stdout(
+ 'Note: analysis errors will result in erroneous migration suggestions.');
+
+ if (options.ignoreErrors) {
+ logger.stdout('Continuing with migration suggestions due to the use of '
+ '--${CommandLineOptions.ignoreErrorsFlag}.');
+ } else {
+ // Fail with how to continue.
+ logger.stdout('');
+ if (importErrorCount != 0) {
+ logger.stdout(
+ 'Unresolved URIs found. Did you forget to run "pub get"?');
+ logger.stdout('');
+ }
+ logger.stdout(
+ 'Please fix the analysis issues (or, force generation of migration '
+ 'suggestions by re-running with '
+ '--${CommandLineOptions.ignoreErrorsFlag}).');
+ exitCode = 1;
+ return;
+ }
+ }
+ }
+
ArgParser _createParser({bool hide = true}) {
var parser = ArgParser();
parser.addFlag(CommandLineOptions.applyChangesFlag,
@@ -306,6 +370,13 @@
'Display this help message. Add --verbose to show hidden options.',
defaultsTo: false,
negatable: false);
+ parser.addFlag(
+ CommandLineOptions.ignoreErrorsFlag,
+ defaultsTo: false,
+ negatable: false,
+ help: 'Attempt to perform null safety analysis even if there are '
+ 'analysis errors in the project.',
+ );
parser.addOption(CommandLineOptions.previewPortOption,
help:
'Run the preview server on the specified port. If not specified, '
@@ -359,6 +430,25 @@
}
}
+ void _displayIssues(Logger logger, String directory,
+ List<AnalysisError> issues, Map<String, LineInfo> lineInfo) {
+ issues.sort((AnalysisError one, AnalysisError two) {
+ if (one.source != two.source) {
+ return one.source.fullName.compareTo(two.source.fullName);
+ }
+ return one.offset - two.offset;
+ });
+
+ _IssueRenderer renderer =
+ _IssueRenderer(logger, directory, pathContext, lineInfo);
+ for (AnalysisError issue in issues) {
+ renderer.render(issue);
+ }
+ }
+
+ bool _isUriError(AnalysisError error) =>
+ error.errorCode == CompileTimeErrorCode.URI_DOES_NOT_EXIST;
+
void _showUsage(bool isVerbose) {
logger.stderr('Usage: $binaryName [options...] [<package directory>]');
@@ -436,7 +526,10 @@
@override
void addSourceFileEdit(
String description, Location location, SourceFileEdit fileEdit) {
- throw UnimplementedError('TODO(paulberry)');
+ suggestions.add(_DartFixSuggestion(description, location: location));
+ for (var sourceEdit in fileEdit.edits) {
+ sourceChange.addEdit(fileEdit.file, fileEdit.fileStamp, sourceEdit);
+ }
}
@override
@@ -470,7 +563,9 @@
final Set<String> pathsToProcess;
- _FixCodeProcessor(this.context)
+ final MigrationCli _migrationCli;
+
+ _FixCodeProcessor(this.context, this._migrationCli)
: pathsToProcess = context.contextRoot
.analyzedFiles()
.where((s) => s.endsWith('.dart'))
@@ -515,14 +610,27 @@
}
}
- Future<List<String>> run() async {
- // TODO(paulberry): do more things from EditDartFix.runAllTasks
+ Future<void> runFirstPhase() async {
+ // Process package
+ await processPackage(context.contextRoot.root);
+
+ // Process each source file.
await processResources((ResolvedUnitResult result) async {
- // TODO(paulberry): check for errors
- if (numPhases > 0) {
+ List<AnalysisError> errors = result.errors
+ .where((error) => error.severity == Severity.error)
+ .toList();
+ if (errors.isNotEmpty) {
+ _migrationCli.fileErrors[result.path] = errors;
+ _migrationCli.lineInfo[result.path] = result.lineInfo;
+ }
+ if (_migrationCli.options.ignoreErrors ||
+ _migrationCli.fileErrors.isEmpty) {
await processCodeTasks(0, result);
}
});
+ }
+
+ Future<List<String>> runLaterPhases() async {
for (var phase = 1; phase < numPhases; phase++) {
await processResources((ResolvedUnitResult result) async {
await processCodeTasks(phase, result);
@@ -533,3 +641,43 @@
return nonNullableFixTask.previewUrls;
}
}
+
+/// Given a Logger and an analysis issue, render the issue to the logger.
+class _IssueRenderer {
+ final Logger logger;
+ final String rootDirectory;
+ final Context pathContext;
+ final Map<String, LineInfo> lineInfo;
+
+ _IssueRenderer(
+ this.logger, this.rootDirectory, this.pathContext, this.lineInfo);
+
+ void render(AnalysisError issue) {
+ // severity • Message ... at foo/bar.dart:6:1 • (error_code)
+ var lineInfoForThisFile = lineInfo[issue.source.fullName];
+ var location = lineInfoForThisFile.getLocation(issue.offset);
+
+ final Ansi ansi = logger.ansi;
+
+ logger.stdout(
+ ' ${ansi.error(_severityToString(issue.severity))} • '
+ '${ansi.emphasized(_removePeriod(issue.message))} '
+ 'at ${pathContext.relative(issue.source.fullName, from: rootDirectory)}'
+ ':${location.lineNumber}:'
+ '${location.columnNumber} '
+ '• (${issue.errorCode.name.toLowerCase()})',
+ );
+ }
+
+ String _severityToString(Severity severity) {
+ switch (severity) {
+ case Severity.error:
+ return 'error';
+ case Severity.warning:
+ return 'warning';
+ case Severity.info:
+ return 'info';
+ }
+ return '???';
+ }
+}
diff --git a/pkg/nnbd_migration/lib/nnbd_migration.dart b/pkg/nnbd_migration/lib/nnbd_migration.dart
index c8670c0..d7d29f4 100644
--- a/pkg/nnbd_migration/lib/nnbd_migration.dart
+++ b/pkg/nnbd_migration/lib/nnbd_migration.dart
@@ -27,6 +27,12 @@
appliedMessage: 'Added a late keyword, due to a hint',
kind: NullabilityFixKind.addLateDueToHint);
+ /// A variable declaration needs to be marked as "late" due to being certainly
+ /// assigned in test setup.
+ static const addLateDueToTestSetup = const NullabilityFixDescription._(
+ appliedMessage: 'Added a late keyword, due to assignment in `setUp`',
+ kind: NullabilityFixKind.addLateDueToTestSetup);
+
/// An expression's value needs to be null-checked.
static const checkExpression = const NullabilityFixDescription._(
appliedMessage: 'Added a non-null assertion to nullable expression',
@@ -206,6 +212,7 @@
enum NullabilityFixKind {
addLate,
addLateDueToHint,
+ addLateDueToTestSetup,
addRequired,
addType,
checkExpression,
diff --git a/pkg/nnbd_migration/lib/src/decorated_type_operations.dart b/pkg/nnbd_migration/lib/src/decorated_type_operations.dart
index 323d579..5de23f2 100644
--- a/pkg/nnbd_migration/lib/src/decorated_type_operations.dart
+++ b/pkg/nnbd_migration/lib/src/decorated_type_operations.dart
@@ -26,6 +26,13 @@
}
@override
+ bool isLocalVariableWithoutDeclaredType(PromotableElement variable) {
+ return variable is LocalVariableElement &&
+ variable.hasImplicitType &&
+ variable.initializer == null;
+ }
+
+ @override
bool isSameType(DecoratedType type1, DecoratedType type2) {
return type1 == type2;
}
diff --git a/pkg/nnbd_migration/lib/src/edge_builder.dart b/pkg/nnbd_migration/lib/src/edge_builder.dart
index 96f2cf9..5d10877 100644
--- a/pkg/nnbd_migration/lib/src/edge_builder.dart
+++ b/pkg/nnbd_migration/lib/src/edge_builder.dart
@@ -137,6 +137,8 @@
/// return statements.
DecoratedType _currentFunctionType;
+ FunctionExpression _currentFunctionExpression;
+
/// The [ClassElement] or [ExtensionElement] of the current class or extension
/// being visited, or null.
Element _currentClassOrExtension;
@@ -332,16 +334,34 @@
} else if (node.operator.type != TokenType.EQ) {
isCompound = true;
}
+
+ var sourceIsSetupCall = false;
+ if (node.leftHandSide is SimpleIdentifier &&
+ _isCurrentFunctionExpressionFoundInTestSetUpCall()) {
+ var assignee = (node.leftHandSide as SimpleIdentifier).staticElement;
+ var enclosingElementOfCurrentFunction =
+ _currentFunctionExpression.declaredElement.enclosingElement;
+ if (enclosingElementOfCurrentFunction == assignee.enclosingElement) {
+ // [node]'s enclosing function is a function expression passed directly
+ // to a call to the test package's `setUp` function, and [node] is an
+ // assignment to a variable declared in the same scope as the call to
+ // `setUp`.
+ sourceIsSetupCall = true;
+ }
+ }
+
var expressionType = _handleAssignment(node.rightHandSide,
destinationExpression: node.leftHandSide,
compoundOperatorInfo: isCompound ? node : null,
- questionAssignNode: isQuestionAssign ? node : null);
+ questionAssignNode: isQuestionAssign ? node : null,
+ sourceIsSetupCall: sourceIsSetupCall);
var conditionalNode = _conditionalNodes[node.leftHandSide];
if (conditionalNode != null) {
expressionType = expressionType.withNode(
NullabilityNode.forLUB(conditionalNode, expressionType.node));
_variables.recordDecoratedExpressionType(node, expressionType);
}
+
return expressionType;
}
@@ -792,7 +812,9 @@
_flowAnalysis.functionExpression_begin(node);
}
_addParametersToFlowAnalysis(node.parameters);
+ var previousFunction = _currentFunctionExpression;
var previousFunctionType = _currentFunctionType;
+ _currentFunctionExpression = node;
_currentFunctionType =
_variables.decoratedElementType(node.declaredElement);
try {
@@ -805,6 +827,7 @@
_flowAnalysis.functionExpression_end();
}
_currentFunctionType = previousFunctionType;
+ _currentFunctionExpression = previousFunction;
}
}
@@ -1143,6 +1166,8 @@
_variables.recordDecoratedExpressionType(node, expressionType);
}
}
+ _handleArgumentErrorCheckNotNull(node);
+ _handleQuiverCheckNotNull(node);
return expressionType;
}
@@ -2048,6 +2073,30 @@
.decoratedTypeParameterBound((type.type as TypeParameterType).element);
}
+ void _handleArgumentErrorCheckNotNull(MethodInvocation node) {
+ var callee = node.methodName.staticElement;
+ var calleeIsStatic = callee is ExecutableElement && callee.isStatic;
+ var target = node.realTarget;
+ bool targetIsArgumentError =
+ (target is SimpleIdentifier && target.name == 'ArgumentError') ||
+ (target is PrefixedIdentifier &&
+ target.identifier.name == 'ArgumentError');
+
+ if (calleeIsStatic &&
+ targetIsArgumentError &&
+ callee.name == 'checkNotNull' &&
+ node.argumentList.arguments.isNotEmpty) {
+ var argument = node.argumentList.arguments.first;
+ if (argument is SimpleIdentifier &&
+ _postDominatedLocals.isReferenceInScope(argument)) {
+ var argumentType =
+ _variables.decoratedElementType(argument.staticElement);
+ _graph.makeNonNullable(argumentType.node,
+ ArgumentErrorCheckNotNullOrigin(source, argument));
+ }
+ }
+ }
+
/// Creates the necessary constraint(s) for an assignment of the given
/// [expression] to a destination whose type is [destinationType].
///
@@ -2063,7 +2112,8 @@
AssignmentExpression compoundOperatorInfo,
AssignmentExpression questionAssignNode,
bool fromDefaultValue = false,
- bool wrapFuture = false}) {
+ bool wrapFuture = false,
+ bool sourceIsSetupCall = false}) {
assert(
(destinationExpression == null) != (destinationType == null),
'Either destinationExpression or destinationType should be supplied, '
@@ -2098,7 +2148,8 @@
throw StateError('No type computed for ${expression.runtimeType} '
'(${expression.toSource()}) offset=${expression.offset}');
}
- EdgeOrigin edgeOrigin = _makeEdgeOrigin(sourceType, expression);
+ EdgeOrigin edgeOrigin = _makeEdgeOrigin(sourceType, expression,
+ isSetupAssignment: sourceIsSetupCall);
if (compoundOperatorInfo != null) {
var compoundOperatorMethod = compoundOperatorInfo.staticElement;
if (compoundOperatorMethod != null) {
@@ -2628,6 +2679,30 @@
}
}
+ /// Check whether [node] is a call to the quiver package's [`checkNotNull`],
+ /// and if so, potentially mark the first argument as non-nullable.
+ ///
+ /// [`checkNotNull`]: https://pub.dev/documentation/quiver/latest/quiver.check/checkNotNull.html
+ void _handleQuiverCheckNotNull(MethodInvocation node) {
+ var callee = node.methodName.staticElement;
+ var calleeUri = callee?.library?.source?.uri;
+ var isQuiverCheckNull = callee?.name == 'checkNotNull' &&
+ calleeUri != null &&
+ calleeUri.scheme == 'package' &&
+ calleeUri.path.startsWith('quiver/');
+
+ if (isQuiverCheckNull && node.argumentList.arguments.isNotEmpty) {
+ var argument = node.argumentList.arguments.first;
+ if (argument is SimpleIdentifier &&
+ _postDominatedLocals.isReferenceInScope(argument)) {
+ var argumentType =
+ _variables.decoratedElementType(argument.staticElement);
+ _graph.makeNonNullable(
+ argumentType.node, QuiverCheckNotNullOrigin(source, argument));
+ }
+ }
+ }
+
DecoratedType _handleTarget(Expression target, String name, Element method) {
if (isDeclaredOnObject(name)) {
return _dispatch(target);
@@ -2651,6 +2726,27 @@
}
}
+ /// Returns whether [_currentFunctionExpression] is an argument to the test
+ /// package's `setUp` function.
+ bool _isCurrentFunctionExpressionFoundInTestSetUpCall() {
+ var parent = _currentFunctionExpression?.parent;
+ if (parent is ArgumentList) {
+ var grandParent = parent.parent;
+ if (grandParent is MethodInvocation) {
+ var enclosingInvocation = grandParent.methodName;
+ if (enclosingInvocation.name == 'setUp') {
+ var uri = enclosingInvocation.staticElement.library?.source?.uri;
+ if (uri != null &&
+ uri.scheme == 'package' &&
+ uri.path.startsWith('test_core/')) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
bool _isPrefix(Expression e) =>
e is SimpleIdentifier && e.staticElement is PrefixElement;
@@ -2702,12 +2798,14 @@
}
}
- EdgeOrigin _makeEdgeOrigin(DecoratedType sourceType, Expression expression) {
+ EdgeOrigin _makeEdgeOrigin(DecoratedType sourceType, Expression expression,
+ {bool isSetupAssignment = false}) {
if (sourceType.type.isDynamic) {
return DynamicAssignmentOrigin(source, expression);
} else {
- ExpressionChecksOrigin expressionChecksOrigin =
- ExpressionChecksOrigin(source, expression, ExpressionChecks());
+ ExpressionChecksOrigin expressionChecksOrigin = ExpressionChecksOrigin(
+ source, expression, ExpressionChecks(),
+ isSetupAssignment: isSetupAssignment);
_variables.recordExpressionChecks(
source, expression, expressionChecksOrigin);
return expressionChecksOrigin;
@@ -2859,7 +2957,9 @@
/// [destination]. [origin] should be used as the origin for any edges
/// created. [hard] indicates whether a hard edge should be created.
/// [sourceIsFunctionLiteral] indicates whether the source of the assignment
- /// is a function literal expression.
+ /// is a function literal expression. [sourceIsSetupCall] indicates whether the
+ /// source of the assignment is a function literal passed to the test
+ /// package's `setUp` function.
void _checkAssignment(EdgeOrigin origin, FixReasonTarget edgeTarget,
{@required DecoratedType source,
@required DecoratedType destination,
diff --git a/pkg/nnbd_migration/lib/src/edge_origin.dart b/pkg/nnbd_migration/lib/src/edge_origin.dart
index aaa8f5d..8348c81 100644
--- a/pkg/nnbd_migration/lib/src/edge_origin.dart
+++ b/pkg/nnbd_migration/lib/src/edge_origin.dart
@@ -430,6 +430,49 @@
EdgeOriginKind get kind => EdgeOriginKind.nonNullAssertion;
}
+/// Edge origin resulting from the presence of a call to quiver's
+/// `checkNotNull`.
+///
+/// For example, in the following code snippet:
+/// import 'package:quiver/check.dart';
+/// void f(int i) {
+/// checkNotNull(i);
+/// }
+///
+/// this class is used for the edge connecting the type of f's `i` parameter to
+/// `never`, due to the `checkNotNull` call proclaiming that `i` is not `null`.
+class QuiverCheckNotNullOrigin extends EdgeOrigin {
+ QuiverCheckNotNullOrigin(Source source, SimpleIdentifier node)
+ : super(source, node);
+
+ @override
+ String get description => 'value checked to be non-null';
+
+ @override
+ EdgeOriginKind get kind => EdgeOriginKind.quiverCheckNotNull;
+}
+
+/// Edge origin resulting from the presence of a call to
+/// `ArgumentError.checkNotNull`.
+///
+/// For example, in the following code snippet:
+/// void f(int i) {
+/// ArgumentError.checkNotNull(i);
+/// }
+///
+/// this class is used for the edge connecting the type of f's `i` parameter to
+/// `never`, due to the `checkNotNull` call proclaiming that `i` is not `null`.
+class ArgumentErrorCheckNotNullOrigin extends EdgeOrigin {
+ ArgumentErrorCheckNotNullOrigin(Source source, SimpleIdentifier node)
+ : super(source, node);
+
+ @override
+ String get description => 'value checked to be non-null';
+
+ @override
+ EdgeOriginKind get kind => EdgeOriginKind.argumentErrorCheckNotNull;
+}
+
/// Edge origin resulting from the presence of an explicit nullability hint
/// comment.
///
diff --git a/pkg/nnbd_migration/lib/src/expression_checks.dart b/pkg/nnbd_migration/lib/src/expression_checks.dart
index 5c281e4..9379c9d 100644
--- a/pkg/nnbd_migration/lib/src/expression_checks.dart
+++ b/pkg/nnbd_migration/lib/src/expression_checks.dart
@@ -31,7 +31,13 @@
class ExpressionChecksOrigin extends EdgeOrigin {
final ExpressionChecks checks;
- ExpressionChecksOrigin(Source source, Expression node, this.checks)
+ /// Whether the origin of the edge is due to the assignment of a variable
+ /// from within function literal argument to the `setUp` function of the test
+ /// package.
+ final bool isSetupAssignment;
+
+ ExpressionChecksOrigin(Source source, Expression node, this.checks,
+ {this.isSetupAssignment = false})
: super(source, node);
@override
diff --git a/pkg/nnbd_migration/lib/src/fix_aggregator.dart b/pkg/nnbd_migration/lib/src/fix_aggregator.dart
index bedc3f5..9200694 100644
--- a/pkg/nnbd_migration/lib/src/fix_aggregator.dart
+++ b/pkg/nnbd_migration/lib/src/fix_aggregator.dart
@@ -194,6 +194,17 @@
}
}
+/// Reasons that a variable declaration is to be made late.
+enum LateAdditionReason {
+ /// It was inferred that the associated variable declaration is to be made
+ /// late through the late-inferring algorithm.
+ inference,
+
+ /// It was inferred that the associated variable declaration is to be made
+ /// late, because it is a test variable which is assigned during setup.
+ testVariableInference,
+}
+
/// Base class representing a kind of change that [FixAggregator] might make to
/// a particular AST node.
abstract class NodeChange<N extends AstNode> {
@@ -203,6 +214,11 @@
/// information.
bool get isInformative => false;
+ Iterable<String> get _toStringParts => const [];
+
+ @override
+ toString() => '$runtimeType(${_toStringParts.join(', ')})';
+
/// Applies this change to the given [node], producing an [EditPlan]. The
/// [aggregator] may be used to gather up any edits to the node's descendants
/// into their own [EditPlan]s.
@@ -235,6 +251,10 @@
NodeChangeForAnnotation() : super._();
@override
+ Iterable<String> get _toStringParts =>
+ [if (changeToRequiredKeyword) 'changeToRequiredKeyword'];
+
+ @override
EditPlan _apply(Annotation node, FixAggregator aggregator) {
if (!changeToRequiredKeyword) {
return aggregator.innerPlanForNode(node);
@@ -265,6 +285,10 @@
bool removeAs = false;
@override
+ Iterable<String> get _toStringParts =>
+ [...super._toStringParts, if (removeAs) 'removeAs'];
+
+ @override
EditPlan _apply(AsExpression node, FixAggregator aggregator) {
if (removeAs) {
return aggregator.planner.extract(node,
@@ -285,6 +309,10 @@
NodeChangeForCompilationUnit() : super._();
@override
+ Iterable<String> get _toStringParts =>
+ [if (removeLanguageVersionComment) 'removeLanguageVersionComment'];
+
+ @override
EditPlan _apply(CompilationUnit node, FixAggregator aggregator) {
List<EditPlan> innerPlans = [];
if (removeLanguageVersionComment) {
@@ -313,6 +341,10 @@
/// the [AtomicEditInfo] for the edit that removes the dead code.
FixReasonInfo conditionReason;
+ @override
+ Iterable<String> get _toStringParts =>
+ [...super._toStringParts, if (conditionValue != null) 'conditionValue'];
+
/// If dead code removal is warranted for [node], returns an [EditPlan] that
/// removes the dead code (and performs appropriate updates within any
/// descendant AST nodes that remain). Otherwise returns `null`.
@@ -424,6 +456,10 @@
NodeChangeForDefaultFormalParameter() : super._();
@override
+ Iterable<String> get _toStringParts =>
+ [if (addRequiredKeyword) 'addRequiredKeyword'];
+
+ @override
EditPlan _apply(DefaultFormalParameter node, FixAggregator aggregator) {
var innerPlan = aggregator.innerPlanForNode(node);
if (!addRequiredKeyword) return innerPlan;
@@ -460,6 +496,12 @@
/// being introduced.
DartType get introducesAsType => _introducesAsType;
+ @override
+ Iterable<String> get _toStringParts => [
+ if (_addsNullCheck) 'addsNullCheck',
+ if (_introducesAsType != null) 'introducesAsType'
+ ];
+
/// Causes a null check to be added to this expression, with the given [info].
void addNullCheck(AtomicEditInfo info, {HintComment hint}) {
assert(!_addsNullCheck);
@@ -570,6 +612,10 @@
/// Indicates whether null-awareness should be removed.
bool removeNullAwareness = false;
+ @override
+ Iterable<String> get _toStringParts =>
+ [...super._toStringParts, if (removeNullAwareness) 'removeNullAwareness'];
+
/// Returns an [EditPlan] that removes null awareness, if appropriate.
/// Otherwise returns `null`.
EditPlan _applyNullAware(N node, FixAggregator aggregator) {
@@ -615,6 +661,10 @@
NodeChangeForSimpleFormalParameter() : super._();
@override
+ Iterable<String> get _toStringParts =>
+ [if (addExplicitType != null) 'addExplicitType'];
+
+ @override
EditPlan _apply(SimpleFormalParameter node, FixAggregator aggregator) {
var innerPlan = aggregator.innerPlanForNode(node);
if (addExplicitType == null) return innerPlan;
@@ -652,6 +702,12 @@
/// it.
HintComment get nullabilityHint => _nullabilityHint;
+ @override
+ Iterable<String> get _toStringParts => [
+ if (_makeNullable) 'makeNullable',
+ if (_nullabilityHint != null) 'nullabilityHint'
+ ];
+
void recordNullability(DecoratedType decoratedType, bool makeNullable,
{HintComment nullabilityHint}) {
_decoratedType = decoratedType;
@@ -709,7 +765,7 @@
/// Indicates whether a "late" annotation should be added to this variable
/// declaration, caused by inference.
- bool addLate = false;
+ LateAdditionReason lateAdditionReason;
/// If a "late" annotation should be added to this variable declaration, and
/// the cause is a "late" hint, the hint that caused it. Otherwise `null`.
@@ -718,10 +774,20 @@
NodeChangeForVariableDeclarationList() : super._();
@override
+ Iterable<String> get _toStringParts => [
+ if (addExplicitType != null) 'addExplicitType',
+ if (lateAdditionReason != null) 'lateAdditionReason',
+ if (lateHint != null) 'lateHint'
+ ];
+
+ @override
EditPlan _apply(VariableDeclarationList node, FixAggregator aggregator) {
List<EditPlan> innerPlans = [];
- if (addLate) {
- var info = AtomicEditInfo(NullabilityFixDescription.addLate, {});
+ if (lateAdditionReason != null) {
+ var description = lateAdditionReason == LateAdditionReason.inference
+ ? NullabilityFixDescription.addLate
+ : NullabilityFixDescription.addLateDueToTestSetup;
+ var info = AtomicEditInfo(description, {});
innerPlans.add(aggregator.planner.insertText(
node,
node.firstTokenAfterCommentAndMetadata.offset,
diff --git a/pkg/nnbd_migration/lib/src/fix_builder.dart b/pkg/nnbd_migration/lib/src/fix_builder.dart
index 76732f9..60abe3f 100644
--- a/pkg/nnbd_migration/lib/src/fix_builder.dart
+++ b/pkg/nnbd_migration/lib/src/fix_builder.dart
@@ -438,8 +438,7 @@
}
if (type.isDynamic) return type;
var ancestor = _findNullabilityContextAncestor(node);
- var context =
- InferenceContext.getContext(ancestor) ?? DynamicTypeImpl.instance;
+ DartType context = _getNullabilityContext(ancestor);
if (!_fixBuilder._typeSystem.isSubtypeOf(type, context)) {
// Either a cast or a null check is needed. We prefer to do a null
// check if we can.
@@ -520,6 +519,35 @@
}
}
+ DartType _getNullabilityContext(Expression node) {
+ var parent = node.parent;
+ if (parent is AssignmentExpression) {
+ var lhs = parent.leftHandSide;
+ if (lhs is SimpleIdentifier) {
+ var lhsElement = lhs.staticElement;
+ if (lhsElement is PromotableElement) {
+ var operatorType = parent.operator.type;
+ switch (operatorType) {
+ case TokenType.EQ:
+ case TokenType.QUESTION_QUESTION_EQ:
+ // When visiting an assignment to a local variable, if the
+ // variable type is promoted, the resolver uses the promoted type
+ // of the variable as the inference context, but it's ok to assign
+ // a different type to the variable (un-doing the promotion). So
+ // for migration purposes, we need to consider the context type to
+ // be the unpromoted type. See
+ // https://github.com/dart-lang/sdk/issues/41411.
+ return lhsElement.type;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ var context = InferenceContext.getContext(node) ?? DynamicTypeImpl.instance;
+ return context;
+ }
+
bool _needsNullCheckDueToStructure(Expression node) {
var parent = node.parent;
if (parent is BinaryExpression) {
@@ -687,20 +715,27 @@
// Check if the nullability node for a single variable declaration has been
// declared to be late.
- var lateNeeded = false;
if (node.variables.length == 1) {
var variableElement = node.variables.single.declaredElement;
- if (_fixBuilder._variables
+ var lateCondition = _fixBuilder._variables
.decoratedElementType(variableElement)
.node
- .isLate) {
- lateNeeded = true;
+ .lateCondition;
+ switch (lateCondition) {
+ case LateCondition.possiblyLate:
+ (_fixBuilder._getChange(node) as NodeChangeForVariableDeclarationList)
+ .lateAdditionReason = LateAdditionReason.inference;
+ break;
+ case LateCondition.possiblyLateDueToTestSetup:
+ (_fixBuilder._getChange(node) as NodeChangeForVariableDeclarationList)
+ .lateAdditionReason = LateAdditionReason.testVariableInference;
+ break;
+ case LateCondition.lateDueToHint:
+ // Handled below.
+ case LateCondition.notLate:
+ // Nothing to do.
}
}
- if (lateNeeded) {
- (_fixBuilder._getChange(node) as NodeChangeForVariableDeclarationList)
- .addLate = true;
- }
var lateHint = _fixBuilder._variables.getLateHint(source, node);
if (lateHint != null) {
diff --git a/pkg/nnbd_migration/lib/src/front_end/info_builder.dart b/pkg/nnbd_migration/lib/src/front_end/info_builder.dart
index e436326..86c298cc 100644
--- a/pkg/nnbd_migration/lib/src/front_end/info_builder.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/info_builder.dart
@@ -182,6 +182,7 @@
edits.add(_changeHint('Change to /*?*/ hint', '/*?*/'));
break;
case NullabilityFixKind.addLate:
+ case NullabilityFixKind.addLateDueToTestSetup:
// We could add an edit to add a `/*?*/` hint, but the offset is a
// little tricky.
break;
diff --git a/pkg/nnbd_migration/lib/src/front_end/resources/resources.g.dart b/pkg/nnbd_migration/lib/src/front_end/resources/resources.g.dart
index 2285f5c..8a3cf79 100644
--- a/pkg/nnbd_migration/lib/src/front_end/resources/resources.g.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/resources/resources.g.dart
@@ -479,7 +479,7 @@
''';
String _migration_js;
-// migration_dart md5 is '4517c0056bd2b39ccf2a244d0548213d'
+// migration_dart md5 is 'cc4f0602969516a30d5bfaecccc3f0f1'
String _migration_js_base64 = '''
KGZ1bmN0aW9uIGRhcnRQcm9ncmFtKCl7ZnVuY3Rpb24gY29weVByb3BlcnRpZXMoYSxiKXt2YXIgdD1P
YmplY3Qua2V5cyhhKQpmb3IodmFyIHM9MDtzPHQubGVuZ3RoO3MrKyl7dmFyIHI9dFtzXQpiW3JdPWFb
@@ -571,2638 +571,2655 @@
OmZ1bmN0aW9uIHh5KGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLiR0aT1jfSwKTUg6ZnVuY3Rp
b24gTUgoYSxiLGMpe3ZhciBfPXRoaXMKXy5hPW51bGwKXy5iPWEKXy5jPWIKXy4kdGk9Y30sCmxKOmZ1
bmN0aW9uIGxKKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLiR0aT1jfSwKVTU6ZnVuY3Rpb24g
-VTUoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuJHRpPWN9LAp2RzpmdW5jdGlvbiB2RyhhLGIs
+VTUoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuJHRpPWN9LApTTzpmdW5jdGlvbiBTTyhhLGIs
Yyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy4kdGk9Y30sClNVOmZ1bmN0aW9uIFNVKCl7fSwKUmU6ZnVu
Y3Rpb24gUmUoKXt9LAp3MjpmdW5jdGlvbiB3Migpe30sCnd2OmZ1bmN0aW9uIHd2KGEpe3RoaXMuYT1h
fSwKZGM6ZnVuY3Rpb24oKXt0aHJvdyBILmIoUC5MNCgiQ2Fubm90IG1vZGlmeSB1bm1vZGlmaWFibGUg
TWFwIikpfSwKTlE6ZnVuY3Rpb24oYSl7dmFyIHQscz1ILkpnKGEpCmlmKHMhPW51bGwpcmV0dXJuIHMK
dD0ibWluaWZpZWQ6IithCnJldHVybiB0fSwKd1Y6ZnVuY3Rpb24oYSxiKXt2YXIgdAppZihiIT1udWxs
-KXt0PWIueAppZih0IT1udWxsKXJldHVybiB0fXJldHVybiB1LmFVLmIoYSl9LApkOmZ1bmN0aW9uKGEp
-e3ZhciB0CmlmKHR5cGVvZiBhPT0ic3RyaW5nIilyZXR1cm4gYQppZih0eXBlb2YgYT09Im51bWJlciIp
-e2lmKGEhPT0wKXJldHVybiIiK2F9ZWxzZSBpZighMD09PWEpcmV0dXJuInRydWUiCmVsc2UgaWYoITE9
-PT1hKXJldHVybiJmYWxzZSIKZWxzZSBpZihhPT1udWxsKXJldHVybiJudWxsIgp0PUouQWMoYSkKaWYo
-dHlwZW9mIHQhPSJzdHJpbmciKXRocm93IEguYihILkkoYSkpCnJldHVybiB0fSwKZVE6ZnVuY3Rpb24o
-YSl7dmFyIHQ9YS4kaWRlbnRpdHlIYXNoCmlmKHQ9PW51bGwpe3Q9TWF0aC5yYW5kb20oKSoweDNmZmZm
-ZmZmfDAKYS4kaWRlbnRpdHlIYXNoPXR9cmV0dXJuIHR9LApIcDpmdW5jdGlvbihhLGIpe3ZhciB0LHMs
-cixxLHAsbyxuPW51bGwKaWYodHlwZW9mIGEhPSJzdHJpbmciKUgudmgoSC5JKGEpKQp0PS9eXHMqWyst
-XT8oKDB4W2EtZjAtOV0rKXwoXGQrKXwoW2EtejAtOV0rKSlccyokL2kuZXhlYyhhKQppZih0PT1udWxs
-KXJldHVybiBuCmlmKDM+PXQubGVuZ3RoKXJldHVybiBILmsodCwzKQpzPUguYyh0WzNdKQppZihiPT1u
-dWxsKXtpZihzIT1udWxsKXJldHVybiBwYXJzZUludChhLDEwKQppZih0WzJdIT1udWxsKXJldHVybiBw
-YXJzZUludChhLDE2KQpyZXR1cm4gbn1pZihiPDJ8fGI+MzYpdGhyb3cgSC5iKFAuVEUoYiwyLDM2LCJy
-YWRpeCIsbikpCmlmKGI9PT0xMCYmcyE9bnVsbClyZXR1cm4gcGFyc2VJbnQoYSwxMCkKaWYoYjwxMHx8
-cz09bnVsbCl7cj1iPD0xMD80NytiOjg2K2IKcT10WzFdCmZvcihwPXEubGVuZ3RoLG89MDtvPHA7Kytv
-KWlmKChDLnhCLlcocSxvKXwzMik+cilyZXR1cm4gbn1yZXR1cm4gcGFyc2VJbnQoYSxiKX0sCmxoOmZ1
-bmN0aW9uKGEpe3ZhciB0PUguSDUoYSkKcmV0dXJuIHR9LApINTpmdW5jdGlvbihhKXt2YXIgdCxzLHIK
-aWYoYSBpbnN0YW5jZW9mIFAuTWgpcmV0dXJuIEguSihILnEoYSksbnVsbCkKaWYoSi5pYShhKT09PUMu
-T2t8fHUuYWsuYihhKSl7dD1DLndiKGEpCmlmKEguQmUodCkpcmV0dXJuIHQKcz1hLmNvbnN0cnVjdG9y
-CmlmKHR5cGVvZiBzPT0iZnVuY3Rpb24iKXtyPXMubmFtZQppZih0eXBlb2Ygcj09InN0cmluZyImJkgu
-QmUocikpcmV0dXJuIHJ9fXJldHVybiBILkooSC5xKGEpLG51bGwpfSwKQmU6ZnVuY3Rpb24oYSl7dmFy
-IHQ9YSE9PSJPYmplY3QiJiZhIT09IiIKcmV0dXJuIHR9LApNMDpmdW5jdGlvbigpe2lmKCEhc2VsZi5s
-b2NhdGlvbilyZXR1cm4gc2VsZi5sb2NhdGlvbi5ocmVmCnJldHVybiBudWxsfSwKVks6ZnVuY3Rpb24o
-YSl7dmFyIHQscyxyLHEscD1hLmxlbmd0aAppZihwPD01MDApcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNv
-ZGUuYXBwbHkobnVsbCxhKQpmb3IodD0iIixzPTA7czxwO3M9cil7cj1zKzUwMApxPXI8cD9yOnAKdCs9
-U3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLGEuc2xpY2UocyxxKSl9cmV0dXJuIHR9LApDcTpm
-dW5jdGlvbihhKXt2YXIgdCxzLHIscT1ILlZNKFtdLHUudCkKZm9yKHQ9YS5sZW5ndGgscz0wO3M8YS5s
-ZW5ndGg7YS5sZW5ndGg9PT10fHwoMCxILmxrKShhKSwrK3Mpe3I9YVtzXQppZighSC5vayhyKSl0aHJv
-dyBILmIoSC5JKHIpKQppZihyPD02NTUzNSlDLk5tLmkocSxyKQplbHNlIGlmKHI8PTExMTQxMTEpe0Mu
-Tm0uaShxLDU1Mjk2KyhDLmpuLndHKHItNjU1MzYsMTApJjEwMjMpKQpDLk5tLmkocSw1NjMyMCsociYx
-MDIzKSl9ZWxzZSB0aHJvdyBILmIoSC5JKHIpKX1yZXR1cm4gSC5WSyhxKX0sCmVUOmZ1bmN0aW9uKGEp
-e3ZhciB0LHMscgpmb3IodD1hLmxlbmd0aCxzPTA7czx0Oysrcyl7cj1hW3NdCmlmKCFILm9rKHIpKXRo
-cm93IEguYihILkkocikpCmlmKHI8MCl0aHJvdyBILmIoSC5JKHIpKQppZihyPjY1NTM1KXJldHVybiBI
-LkNxKGEpfXJldHVybiBILlZLKGEpfSwKZnc6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxCmlmKGM8
-PTUwMCYmYj09PTAmJmM9PT1hLmxlbmd0aClyZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShu
-dWxsLGEpCmZvcih0PWIscz0iIjt0PGM7dD1yKXtyPXQrNTAwCnE9cjxjP3I6YwpzKz1TdHJpbmcuZnJv
-bUNoYXJDb2RlLmFwcGx5KG51bGwsYS5zdWJhcnJheSh0LHEpKX1yZXR1cm4gc30sCkx3OmZ1bmN0aW9u
-KGEpe3ZhciB0CmlmKDA8PWEpe2lmKGE8PTY1NTM1KXJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKGEp
-CmlmKGE8PTExMTQxMTEpe3Q9YS02NTUzNgpyZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZSgoNTUyOTZ8
-Qy5qbi53Ryh0LDEwKSk+Pj4wLDU2MzIwfHQmMTAyMyl9fXRocm93IEguYihQLlRFKGEsMCwxMTE0MTEx
-LG51bGwsbnVsbCkpfSwKbzI6ZnVuY3Rpb24oYSl7aWYoYS5kYXRlPT09dm9pZCAwKWEuZGF0ZT1uZXcg
-RGF0ZShhLmEpCnJldHVybiBhLmRhdGV9LAp0SjpmdW5jdGlvbihhKXt2YXIgdD1ILm8yKGEpLmdldEZ1
-bGxZZWFyKCkrMApyZXR1cm4gdH0sCk5TOmZ1bmN0aW9uKGEpe3ZhciB0PUgubzIoYSkuZ2V0TW9udGgo
-KSsxCnJldHVybiB0fSwKakE6ZnVuY3Rpb24oYSl7dmFyIHQ9SC5vMihhKS5nZXREYXRlKCkrMApyZXR1
-cm4gdH0sCklYOmZ1bmN0aW9uKGEpe3ZhciB0PUgubzIoYSkuZ2V0SG91cnMoKSswCnJldHVybiB0fSwK
-Y2g6ZnVuY3Rpb24oYSl7dmFyIHQ9SC5vMihhKS5nZXRNaW51dGVzKCkrMApyZXR1cm4gdH0sCkpkOmZ1
-bmN0aW9uKGEpe3ZhciB0PUgubzIoYSkuZ2V0U2Vjb25kcygpKzAKcmV0dXJuIHR9LApWYTpmdW5jdGlv
-bihhKXt2YXIgdD1ILm8yKGEpLmdldE1pbGxpc2Vjb25kcygpKzAKcmV0dXJuIHR9LAp6bzpmdW5jdGlv
-bihhLGIsYyl7dmFyIHQscyxyPXt9CnIuYT0wCnQ9W10Kcz1bXQpyLmE9Yi5sZW5ndGgKQy5ObS5GVih0
-LGIpCnIuYj0iIgppZihjIT1udWxsJiZjLmEhPT0wKWMuSygwLG5ldyBILkNqKHIscyx0KSkKIiIrci5h
-CnJldHVybiBKLkp5KGEsbmV3IEguTEkoQy5UZSwwLHQscywwKSl9LApFazpmdW5jdGlvbihhLGIsYyl7
-dmFyIHQscyxyLHEKaWYoYiBpbnN0YW5jZW9mIEFycmF5KXQ9Yz09bnVsbHx8Yy5hPT09MAplbHNlIHQ9
-ITEKaWYodCl7cz1iCnI9cy5sZW5ndGgKaWYocj09PTApe2lmKCEhYS4kMClyZXR1cm4gYS4kMCgpfWVs
-c2UgaWYocj09PTEpe2lmKCEhYS4kMSlyZXR1cm4gYS4kMShzWzBdKX1lbHNlIGlmKHI9PT0yKXtpZigh
-IWEuJDIpcmV0dXJuIGEuJDIoc1swXSxzWzFdKX1lbHNlIGlmKHI9PT0zKXtpZighIWEuJDMpcmV0dXJu
-IGEuJDMoc1swXSxzWzFdLHNbMl0pfWVsc2UgaWYocj09PTQpe2lmKCEhYS4kNClyZXR1cm4gYS4kNChz
-WzBdLHNbMV0sc1syXSxzWzNdKX1lbHNlIGlmKHI9PT01KWlmKCEhYS4kNSlyZXR1cm4gYS4kNShzWzBd
-LHNbMV0sc1syXSxzWzNdLHNbNF0pCnE9YVsiIisiJCIrcl0KaWYocSE9bnVsbClyZXR1cm4gcS5hcHBs
-eShhLHMpfXJldHVybiBILmUxKGEsYixjKX0sCmUxOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscSxw
-LG8sbixtLGwsaz1iIGluc3RhbmNlb2YgQXJyYXk/YjpQLkNIKGIsITAsdS56KSxqPWsubGVuZ3RoLGk9
-YS4kUgppZihqPGkpcmV0dXJuIEguem8oYSxrLGMpCnQ9YS4kRApzPXQ9PW51bGwKcj0hcz90KCk6bnVs
-bApxPUouaWEoYSkKcD1xLiRDCmlmKHR5cGVvZiBwPT0ic3RyaW5nIilwPXFbcF0KaWYocyl7aWYoYyE9
-bnVsbCYmYy5hIT09MClyZXR1cm4gSC56byhhLGssYykKaWYoaj09PWkpcmV0dXJuIHAuYXBwbHkoYSxr
-KQpyZXR1cm4gSC56byhhLGssYyl9aWYociBpbnN0YW5jZW9mIEFycmF5KXtpZihjIT1udWxsJiZjLmEh
-PT0wKXJldHVybiBILnpvKGEsayxjKQppZihqPmkrci5sZW5ndGgpcmV0dXJuIEguem8oYSxrLG51bGwp
-CkMuTm0uRlYoayxyLnNsaWNlKGotaSkpCnJldHVybiBwLmFwcGx5KGEsayl9ZWxzZXtpZihqPmkpcmV0
-dXJuIEguem8oYSxrLGMpCm89T2JqZWN0LmtleXMocikKaWYoYz09bnVsbClmb3Iocz1vLmxlbmd0aCxu
-PTA7bjxvLmxlbmd0aDtvLmxlbmd0aD09PXN8fCgwLEgubGspKG8pLCsrbilDLk5tLmkoayxyW0guYyhv
-W25dKV0pCmVsc2V7Zm9yKHM9by5sZW5ndGgsbT0wLG49MDtuPG8ubGVuZ3RoO28ubGVuZ3RoPT09c3x8
-KDAsSC5saykobyksKytuKXtsPUguYyhvW25dKQppZihjLng0KGwpKXsrK20KQy5ObS5pKGssYy5xKDAs
-bCkpfWVsc2UgQy5ObS5pKGsscltsXSl9aWYobSE9PWMuYSlyZXR1cm4gSC56byhhLGssYyl9cmV0dXJu
-IHAuYXBwbHkoYSxrKX19LApwWTpmdW5jdGlvbihhKXt0aHJvdyBILmIoSC5JKGEpKX0sCms6ZnVuY3Rp
-b24oYSxiKXtpZihhPT1udWxsKUouSChhKQp0aHJvdyBILmIoSC5IWShhLGIpKX0sCkhZOmZ1bmN0aW9u
-KGEsYil7dmFyIHQscyxyPSJpbmRleCIKaWYoIUgub2soYikpcmV0dXJuIG5ldyBQLkFUKCEwLGIscixu
-dWxsKQp0PUguV1koSi5IKGEpKQppZighKGI8MCkpe2lmKHR5cGVvZiB0IT09Im51bWJlciIpcmV0dXJu
-IEgucFkodCkKcz1iPj10fWVsc2Ugcz0hMAppZihzKXJldHVybiBQLnQoYixhLHIsbnVsbCx0KQpyZXR1
-cm4gUC5PNyhiLHIpfSwKYXU6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PW51bGwKaWYoYT5jKXJldHVybiBQ
-LlRFKGEsMCxjLCJzdGFydCIsdCkKaWYoYiE9bnVsbCl7aWYoIUgub2soYikpcmV0dXJuIG5ldyBQLkFU
-KCEwLGIsImVuZCIsdCkKaWYoYjxhfHxiPmMpcmV0dXJuIFAuVEUoYixhLGMsImVuZCIsdCl9cmV0dXJu
-IG5ldyBQLkFUKCEwLGIsImVuZCIsdCl9LApJOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5BVCghMCxh
-LG51bGwsbnVsbCl9LApiOmZ1bmN0aW9uKGEpe3ZhciB0CmlmKGE9PW51bGwpYT1uZXcgUC5MSygpCnQ9
-bmV3IEVycm9yKCkKdC5kYXJ0RXhjZXB0aW9uPWEKaWYoImRlZmluZVByb3BlcnR5IiBpbiBPYmplY3Qp
-e09iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LCJtZXNzYWdlIix7Z2V0OkguSnV9KQp0Lm5hbWU9IiJ9ZWxz
-ZSB0LnRvU3RyaW5nPUguSnUKcmV0dXJuIHR9LApKdTpmdW5jdGlvbigpe3JldHVybiBKLkFjKHRoaXMu
-ZGFydEV4Y2VwdGlvbil9LAp2aDpmdW5jdGlvbihhKXt0aHJvdyBILmIoYSl9LApsazpmdW5jdGlvbihh
-KXt0aHJvdyBILmIoUC5hNChhKSl9LApjTTpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8KYT1ILmVB
-KGEucmVwbGFjZShTdHJpbmcoe30pLCckcmVjZWl2ZXIkJykpCnQ9YS5tYXRjaCgvXFxcJFthLXpBLVpd
-K1xcXCQvZykKaWYodD09bnVsbCl0PUguVk0oW10sdS5zKQpzPXQuaW5kZXhPZigiXFwkYXJndW1lbnRz
-XFwkIikKcj10LmluZGV4T2YoIlxcJGFyZ3VtZW50c0V4cHJcXCQiKQpxPXQuaW5kZXhPZigiXFwkZXhw
-clxcJCIpCnA9dC5pbmRleE9mKCJcXCRtZXRob2RcXCQiKQpvPXQuaW5kZXhPZigiXFwkcmVjZWl2ZXJc
-XCQiKQpyZXR1cm4gbmV3IEguZjkoYS5yZXBsYWNlKG5ldyBSZWdFeHAoJ1xcXFxcXCRhcmd1bWVudHNc
-XFxcXFwkJywnZycpLCcoKD86eHxbXnhdKSopJykucmVwbGFjZShuZXcgUmVnRXhwKCdcXFxcXFwkYXJn
-dW1lbnRzRXhwclxcXFxcXCQnLCdnJyksJygoPzp4fFteeF0pKiknKS5yZXBsYWNlKG5ldyBSZWdFeHAo
-J1xcXFxcXCRleHByXFxcXFxcJCcsJ2cnKSwnKCg/Onh8W154XSkqKScpLnJlcGxhY2UobmV3IFJlZ0V4
-cCgnXFxcXFxcJG1ldGhvZFxcXFxcXCQnLCdnJyksJygoPzp4fFteeF0pKiknKS5yZXBsYWNlKG5ldyBS
-ZWdFeHAoJ1xcXFxcXCRyZWNlaXZlclxcXFxcXCQnLCdnJyksJygoPzp4fFteeF0pKiknKSxzLHIscSxw
-LG8pfSwKUzc6ZnVuY3Rpb24oYSl7cmV0dXJuIGZ1bmN0aW9uKCRleHByJCl7dmFyICRhcmd1bWVudHNF
-eHByJD0nJGFyZ3VtZW50cyQnCnRyeXskZXhwciQuJG1ldGhvZCQoJGFyZ3VtZW50c0V4cHIkKX1jYXRj
-aCh0KXtyZXR1cm4gdC5tZXNzYWdlfX0oYSl9LApNajpmdW5jdGlvbihhKXtyZXR1cm4gZnVuY3Rpb24o
-JGV4cHIkKXt0cnl7JGV4cHIkLiRtZXRob2QkfWNhdGNoKHQpe3JldHVybiB0Lm1lc3NhZ2V9fShhKX0s
-CklqOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBILlcwKGEsYj09bnVsbD9udWxsOmIubWV0aG9kKX0s
-ClQzOmZ1bmN0aW9uKGEsYil7dmFyIHQ9Yj09bnVsbCxzPXQ/bnVsbDpiLm1ldGhvZApyZXR1cm4gbmV3
-IEguYXooYSxzLHQ/bnVsbDpiLnJlY2VpdmVyKX0sClJ1OmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAs
-byxuLG0sbCxrLGosaSxoLGcsZj1udWxsLGU9bmV3IEguQW0oYSkKaWYoYT09bnVsbClyZXR1cm4gZgpp
-ZihhIGluc3RhbmNlb2YgSC5icSlyZXR1cm4gZS4kMShhLmEpCmlmKHR5cGVvZiBhIT09Im9iamVjdCIp
-cmV0dXJuIGEKaWYoImRhcnRFeGNlcHRpb24iIGluIGEpcmV0dXJuIGUuJDEoYS5kYXJ0RXhjZXB0aW9u
-KQplbHNlIGlmKCEoIm1lc3NhZ2UiIGluIGEpKXJldHVybiBhCnQ9YS5tZXNzYWdlCmlmKCJudW1iZXIi
-IGluIGEmJnR5cGVvZiBhLm51bWJlcj09Im51bWJlciIpe3M9YS5udW1iZXIKcj1zJjY1NTM1CmlmKChD
-LmpuLndHKHMsMTYpJjgxOTEpPT09MTApc3dpdGNoKHIpe2Nhc2UgNDM4OnJldHVybiBlLiQxKEguVDMo
-SC5kKHQpKyIgKEVycm9yICIrcisiKSIsZikpCmNhc2UgNDQ1OmNhc2UgNTAwNzpyZXR1cm4gZS4kMShI
-LklqKEguZCh0KSsiIChFcnJvciAiK3IrIikiLGYpKX19aWYoYSBpbnN0YW5jZW9mIFR5cGVFcnJvcil7
-cT0kLlNuKCkKcD0kLmxxKCkKbz0kLk45KCkKbj0kLmlJKCkKbT0kLlVOKCkKbD0kLlpoKCkKaz0kLnJO
-KCkKJC5jMygpCmo9JC5ISygpCmk9JC5yMSgpCmg9cS5xUyh0KQppZihoIT1udWxsKXJldHVybiBlLiQx
-KEguVDMoSC5jKHQpLGgpKQplbHNle2g9cC5xUyh0KQppZihoIT1udWxsKXtoLm1ldGhvZD0iY2FsbCIK
-cmV0dXJuIGUuJDEoSC5UMyhILmModCksaCkpfWVsc2V7aD1vLnFTKHQpCmlmKGg9PW51bGwpe2g9bi5x
-Uyh0KQppZihoPT1udWxsKXtoPW0ucVModCkKaWYoaD09bnVsbCl7aD1sLnFTKHQpCmlmKGg9PW51bGwp
-e2g9ay5xUyh0KQppZihoPT1udWxsKXtoPW4ucVModCkKaWYoaD09bnVsbCl7aD1qLnFTKHQpCmlmKGg9
-PW51bGwpe2g9aS5xUyh0KQpnPWghPW51bGx9ZWxzZSBnPSEwfWVsc2UgZz0hMH1lbHNlIGc9ITB9ZWxz
-ZSBnPSEwfWVsc2UgZz0hMH1lbHNlIGc9ITB9ZWxzZSBnPSEwCmlmKGcpcmV0dXJuIGUuJDEoSC5JaihI
-LmModCksaCkpfX1yZXR1cm4gZS4kMShuZXcgSC52Vih0eXBlb2YgdD09InN0cmluZyI/dDoiIikpfWlm
-KGEgaW5zdGFuY2VvZiBSYW5nZUVycm9yKXtpZih0eXBlb2YgdD09InN0cmluZyImJnQuaW5kZXhPZigi
-Y2FsbCBzdGFjayIpIT09LTEpcmV0dXJuIG5ldyBQLktZKCkKdD1mdW5jdGlvbihiKXt0cnl7cmV0dXJu
-IFN0cmluZyhiKX1jYXRjaChkKXt9cmV0dXJuIG51bGx9KGEpCnJldHVybiBlLiQxKG5ldyBQLkFUKCEx
-LGYsZix0eXBlb2YgdD09InN0cmluZyI/dC5yZXBsYWNlKC9eUmFuZ2VFcnJvcjpccyovLCIiKTp0KSl9
-aWYodHlwZW9mIEludGVybmFsRXJyb3I9PSJmdW5jdGlvbiImJmEgaW5zdGFuY2VvZiBJbnRlcm5hbEVy
-cm9yKWlmKHR5cGVvZiB0PT0ic3RyaW5nIiYmdD09PSJ0b28gbXVjaCByZWN1cnNpb24iKXJldHVybiBu
-ZXcgUC5LWSgpCnJldHVybiBhfSwKdHM6ZnVuY3Rpb24oYSl7dmFyIHQKaWYoYSBpbnN0YW5jZW9mIEgu
-YnEpcmV0dXJuIGEuYgppZihhPT1udWxsKXJldHVybiBuZXcgSC5YTyhhKQp0PWEuJGNhY2hlZFRyYWNl
-CmlmKHQhPW51bGwpcmV0dXJuIHQKcmV0dXJuIGEuJGNhY2hlZFRyYWNlPW5ldyBILlhPKGEpfSwKQjc6
-ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscT1hLmxlbmd0aApmb3IodD0wO3Q8cTt0PXIpe3M9dCsxCnI9
-cysxCmIuWSgwLGFbdF0sYVtzXSl9cmV0dXJuIGJ9LApmdDpmdW5jdGlvbihhLGIsYyxkLGUsZil7dS5a
-LmEoYSkKc3dpdGNoKEguV1koYikpe2Nhc2UgMDpyZXR1cm4gYS4kMCgpCmNhc2UgMTpyZXR1cm4gYS4k
-MShjKQpjYXNlIDI6cmV0dXJuIGEuJDIoYyxkKQpjYXNlIDM6cmV0dXJuIGEuJDMoYyxkLGUpCmNhc2Ug
-NDpyZXR1cm4gYS4kNChjLGQsZSxmKX10aHJvdyBILmIobmV3IFAuQ0QoIlVuc3VwcG9ydGVkIG51bWJl
-ciBvZiBhcmd1bWVudHMgZm9yIHdyYXBwZWQgY2xvc3VyZSIpKX0sCnRSOmZ1bmN0aW9uKGEsYil7dmFy
-IHQKaWYoYT09bnVsbClyZXR1cm4gbnVsbAp0PWEuJGlkZW50aXR5CmlmKCEhdClyZXR1cm4gdAp0PWZ1
-bmN0aW9uKGMsZCxlKXtyZXR1cm4gZnVuY3Rpb24oZixnLGgsaSl7cmV0dXJuIGUoYyxkLGYsZyxoLGkp
-fX0oYSxiLEguZnQpCmEuJGlkZW50aXR5PXQKcmV0dXJuIHR9LAppQTpmdW5jdGlvbihhLGIsYyxkLGUs
-ZixnKXt2YXIgdCxzLHIscSxwLG8sbixtLGw9YlswXSxrPWwuJGNhbGxOYW1lLGo9ZT9PYmplY3QuY3Jl
-YXRlKG5ldyBILnp4KCkuY29uc3RydWN0b3IucHJvdG90eXBlKTpPYmplY3QuY3JlYXRlKG5ldyBILmp5
-KG51bGwsbnVsbCxudWxsLCIiKS5jb25zdHJ1Y3Rvci5wcm90b3R5cGUpCmouJGluaXRpYWxpemU9ai5j
-b25zdHJ1Y3RvcgppZihlKXQ9ZnVuY3Rpb24gc3RhdGljX3RlYXJfb2ZmKCl7dGhpcy4kaW5pdGlhbGl6
-ZSgpfQplbHNle3M9JC55agppZih0eXBlb2YgcyE9PSJudW1iZXIiKXJldHVybiBzLmgoKQokLnlqPXMr
-MQpzPW5ldyBGdW5jdGlvbigiYSxiLGMsZCIrcywidGhpcy4kaW5pdGlhbGl6ZShhLGIsYyxkIitzKyIp
-IikKdD1zfWouY29uc3RydWN0b3I9dAp0LnByb3RvdHlwZT1qCmlmKCFlKXtyPUguYngoYSxsLGYpCnIu
-JHJlZmxlY3Rpb25JbmZvPWR9ZWxzZXtqLiRzdGF0aWNfbmFtZT1nCnI9bH1xPUguaW0oZCxlLGYpCmou
-JFM9cQpqW2tdPXIKZm9yKHA9cixvPTE7bzxiLmxlbmd0aDsrK28pe249YltvXQptPW4uJGNhbGxOYW1l
-CmlmKG0hPW51bGwpe249ZT9uOkguYngoYSxuLGYpCmpbbV09bn1pZihvPT09Yyl7bi4kcmVmbGVjdGlv
-bkluZm89ZApwPW59fWouJEM9cApqLiRSPWwuJFIKai4kRD1sLiRECnJldHVybiB0fSwKaW06ZnVuY3Rp
-b24oYSxiLGMpe3ZhciB0CmlmKHR5cGVvZiBhPT0ibnVtYmVyIilyZXR1cm4gZnVuY3Rpb24oZCxlKXty
-ZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gZChlKX19KEguQnAsYSkKaWYodHlwZW9mIGE9PSJzdHJpbmci
-KXtpZihiKXRocm93IEguYigiQ2Fubm90IGNvbXB1dGUgc2lnbmF0dXJlIGZvciBzdGF0aWMgdGVhcm9m
-Zi4iKQp0PWM/SC5QVzpILlRuCnJldHVybiBmdW5jdGlvbihkLGUpe3JldHVybiBmdW5jdGlvbigpe3Jl
-dHVybiBlKHRoaXMsZCl9fShhLHQpfXRocm93IEguYigiRXJyb3IgaW4gZnVuY3Rpb25UeXBlIG9mIHRl
-YXJvZmYiKX0sCnZxOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0PUguRFYKc3dpdGNoKGI/LTE6YSl7Y2Fz
-ZSAwOnJldHVybiBmdW5jdGlvbihlLGYpe3JldHVybiBmdW5jdGlvbigpe3JldHVybiBmKHRoaXMpW2Vd
-KCl9fShjLHQpCmNhc2UgMTpyZXR1cm4gZnVuY3Rpb24oZSxmKXtyZXR1cm4gZnVuY3Rpb24oZyl7cmV0
-dXJuIGYodGhpcylbZV0oZyl9fShjLHQpCmNhc2UgMjpyZXR1cm4gZnVuY3Rpb24oZSxmKXtyZXR1cm4g
-ZnVuY3Rpb24oZyxoKXtyZXR1cm4gZih0aGlzKVtlXShnLGgpfX0oYyx0KQpjYXNlIDM6cmV0dXJuIGZ1
-bmN0aW9uKGUsZil7cmV0dXJuIGZ1bmN0aW9uKGcsaCxpKXtyZXR1cm4gZih0aGlzKVtlXShnLGgsaSl9
-fShjLHQpCmNhc2UgNDpyZXR1cm4gZnVuY3Rpb24oZSxmKXtyZXR1cm4gZnVuY3Rpb24oZyxoLGksail7
-cmV0dXJuIGYodGhpcylbZV0oZyxoLGksail9fShjLHQpCmNhc2UgNTpyZXR1cm4gZnVuY3Rpb24oZSxm
-KXtyZXR1cm4gZnVuY3Rpb24oZyxoLGksaixrKXtyZXR1cm4gZih0aGlzKVtlXShnLGgsaSxqLGspfX0o
-Yyx0KQpkZWZhdWx0OnJldHVybiBmdW5jdGlvbihlLGYpe3JldHVybiBmdW5jdGlvbigpe3JldHVybiBl
-LmFwcGx5KGYodGhpcyksYXJndW1lbnRzKX19KGQsdCl9fSwKYng6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0
-LHMscixxLHAsbyxuCmlmKGMpcmV0dXJuIEguSGYoYSxiKQp0PWIuJHN0dWJOYW1lCnM9Yi5sZW5ndGgK
-cj1hW3RdCnE9Yj09bnVsbD9yPT1udWxsOmI9PT1yCnA9IXF8fHM+PTI3CmlmKHApcmV0dXJuIEgudnEo
-cywhcSx0LGIpCmlmKHM9PT0wKXtxPSQueWoKaWYodHlwZW9mIHEhPT0ibnVtYmVyIilyZXR1cm4gcS5o
-KCkKJC55aj1xKzEKbz0ic2VsZiIrcQpyZXR1cm4gbmV3IEZ1bmN0aW9uKCJyZXR1cm4gZnVuY3Rpb24o
-KXt2YXIgIitvKyIgPSB0aGlzLiIrSC5kKEgub04oKSkrIjtyZXR1cm4gIitvKyIuIitILmQodCkrIigp
-O30iKSgpfW49ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6Ii5zcGxpdCgiIikuc3BsaWNlKDAscyku
-am9pbigiLCIpCnE9JC55agppZih0eXBlb2YgcSE9PSJudW1iZXIiKXJldHVybiBxLmgoKQokLnlqPXEr
-MQpuKz1xCnJldHVybiBuZXcgRnVuY3Rpb24oInJldHVybiBmdW5jdGlvbigiK24rIil7cmV0dXJuIHRo
-aXMuIitILmQoSC5vTigpKSsiLiIrSC5kKHQpKyIoIituKyIpO30iKSgpfSwKWjQ6ZnVuY3Rpb24oYSxi
-LGMsZCl7dmFyIHQ9SC5EVixzPUgueVMKc3dpdGNoKGI/LTE6YSl7Y2FzZSAwOnRocm93IEguYihILkVm
-KCJJbnRlcmNlcHRlZCBmdW5jdGlvbiB3aXRoIG5vIGFyZ3VtZW50cy4iKSkKY2FzZSAxOnJldHVybiBm
-dW5jdGlvbihlLGYsZyl7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIGYodGhpcylbZV0oZyh0aGlzKSl9
-fShjLHQscykKY2FzZSAyOnJldHVybiBmdW5jdGlvbihlLGYsZyl7cmV0dXJuIGZ1bmN0aW9uKGgpe3Jl
-dHVybiBmKHRoaXMpW2VdKGcodGhpcyksaCl9fShjLHQscykKY2FzZSAzOnJldHVybiBmdW5jdGlvbihl
-LGYsZyl7cmV0dXJuIGZ1bmN0aW9uKGgsaSl7cmV0dXJuIGYodGhpcylbZV0oZyh0aGlzKSxoLGkpfX0o
-Yyx0LHMpCmNhc2UgNDpyZXR1cm4gZnVuY3Rpb24oZSxmLGcpe3JldHVybiBmdW5jdGlvbihoLGksail7
-cmV0dXJuIGYodGhpcylbZV0oZyh0aGlzKSxoLGksail9fShjLHQscykKY2FzZSA1OnJldHVybiBmdW5j
-dGlvbihlLGYsZyl7cmV0dXJuIGZ1bmN0aW9uKGgsaSxqLGspe3JldHVybiBmKHRoaXMpW2VdKGcodGhp
-cyksaCxpLGosayl9fShjLHQscykKY2FzZSA2OnJldHVybiBmdW5jdGlvbihlLGYsZyl7cmV0dXJuIGZ1
-bmN0aW9uKGgsaSxqLGssbCl7cmV0dXJuIGYodGhpcylbZV0oZyh0aGlzKSxoLGksaixrLGwpfX0oYyx0
-LHMpCmRlZmF1bHQ6cmV0dXJuIGZ1bmN0aW9uKGUsZixnLGgpe3JldHVybiBmdW5jdGlvbigpe2g9W2co
-dGhpcyldCkFycmF5LnByb3RvdHlwZS5wdXNoLmFwcGx5KGgsYXJndW1lbnRzKQpyZXR1cm4gZS5hcHBs
-eShmKHRoaXMpLGgpfX0oZCx0LHMpfX0sCkhmOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvLG49
-SC5vTigpLG09JC5QNAppZihtPT1udWxsKW09JC5QND1ILkUyKCJyZWNlaXZlciIpCnQ9Yi4kc3R1Yk5h
-bWUKcz1iLmxlbmd0aApyPWFbdF0KcT1iPT1udWxsP3I9PW51bGw6Yj09PXIKcD0hcXx8cz49MjgKaWYo
-cClyZXR1cm4gSC5aNChzLCFxLHQsYikKaWYocz09PTEpe3E9InJldHVybiBmdW5jdGlvbigpe3JldHVy
-biB0aGlzLiIrSC5kKG4pKyIuIitILmQodCkrIih0aGlzLiIrbSsiKTsiCnA9JC55agppZih0eXBlb2Yg
-cCE9PSJudW1iZXIiKXJldHVybiBwLmgoKQokLnlqPXArMQpyZXR1cm4gbmV3IEZ1bmN0aW9uKHErcCsi
-fSIpKCl9bz0iYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoiLnNwbGl0KCIiKS5zcGxpY2UoMCxzLTEp
-LmpvaW4oIiwiKQpxPSJyZXR1cm4gZnVuY3Rpb24oIitvKyIpe3JldHVybiB0aGlzLiIrSC5kKG4pKyIu
-IitILmQodCkrIih0aGlzLiIrbSsiLCAiK28rIik7IgpwPSQueWoKaWYodHlwZW9mIHAhPT0ibnVtYmVy
-IilyZXR1cm4gcC5oKCkKJC55aj1wKzEKcmV0dXJuIG5ldyBGdW5jdGlvbihxK3ArIn0iKSgpfSwKS3E6
-ZnVuY3Rpb24oYSxiLGMsZCxlLGYsZyl7cmV0dXJuIEguaUEoYSxiLGMsZCwhIWUsISFmLGcpfSwKVG46
-ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSC5jRSh2LnR5cGVVbml2ZXJzZSxILnEoYS5hKSxiKX0sClBXOmZ1
-bmN0aW9uKGEsYil7cmV0dXJuIEguY0Uodi50eXBlVW5pdmVyc2UsSC5xKGEuYyksYil9LApEVjpmdW5j
-dGlvbihhKXtyZXR1cm4gYS5hfSwKeVM6ZnVuY3Rpb24oYSl7cmV0dXJuIGEuY30sCm9OOmZ1bmN0aW9u
-KCl7dmFyIHQ9JC5tSgpyZXR1cm4gdD09bnVsbD8kLm1KPUguRTIoInNlbGYiKTp0fSwKRTI6ZnVuY3Rp
-b24oYSl7dmFyIHQscyxyLHE9bmV3IEguankoInNlbGYiLCJ0YXJnZXQiLCJyZWNlaXZlciIsIm5hbWUi
-KSxwPUouRXAoT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMocSksdS56KQpmb3IodD1wLmxlbmd0aCxz
-PTA7czx0Oysrcyl7cj1wW3NdCmlmKHFbcl09PT1hKXJldHVybiByfXRocm93IEguYihQLnhZKCJGaWVs
-ZCBuYW1lICIrYSsiIG5vdCBmb3VuZC4iKSl9LApvVDpmdW5jdGlvbihhKXtpZihhPT1udWxsKUguZk8o
-ImJvb2xlYW4gZXhwcmVzc2lvbiBtdXN0IG5vdCBiZSBudWxsIikKcmV0dXJuIGF9LApmTzpmdW5jdGlv
-bihhKXt0aHJvdyBILmIobmV3IEgua1koYSkpfSwKYWc6ZnVuY3Rpb24oYSl7dGhyb3cgSC5iKG5ldyBQ
-LnQ3KGEpKX0sCkVmOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgSC5FcShhKX0sCllnOmZ1bmN0aW9uKGEp
-e3JldHVybiB2LmdldElzb2xhdGVUYWcoYSl9LApWTTpmdW5jdGlvbihhLGIpe2Fbdi5hcnJheVJ0aV09
-YgpyZXR1cm4gYX0sCm9YOmZ1bmN0aW9uKGEpe2lmKGE9PW51bGwpcmV0dXJuIG51bGwKcmV0dXJuIGEu
-JHRpfSwKSU06ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBILlk5KGFbIiRhIitILmQoYyldLEgub1goYikp
-fSwKWTk6ZnVuY3Rpb24oYSxiKXtpZihhPT1udWxsKXJldHVybiBiCmE9YS5hcHBseShudWxsLGIpCmlm
-KGE9PW51bGwpcmV0dXJuIG51bGwKaWYoQXJyYXkuaXNBcnJheShhKSlyZXR1cm4gYQppZih0eXBlb2Yg
-YT09ImZ1bmN0aW9uIilyZXR1cm4gYS5hcHBseShudWxsLGIpCnJldHVybiBifSwKSUc6ZnVuY3Rpb24o
-YSxiLGMpe3JldHVybiBhLmFwcGx5KGIsSC5JTShKLmlhKGIpLGIsYykpfSwKaXc6ZnVuY3Rpb24oYSxi
-LGMpe09iamVjdC5kZWZpbmVQcm9wZXJ0eShhLGIse3ZhbHVlOmMsZW51bWVyYWJsZTpmYWxzZSx3cml0
-YWJsZTp0cnVlLGNvbmZpZ3VyYWJsZTp0cnVlfSl9LApHOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHA9
-SC5jKCQueS4kMShhKSksbz0kLmpbcF0KaWYobyE9bnVsbCl7T2JqZWN0LmRlZmluZVByb3BlcnR5KGEs
-di5kaXNwYXRjaFByb3BlcnR5TmFtZSx7dmFsdWU6byxlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxlOnRy
-dWUsY29uZmlndXJhYmxlOnRydWV9KQpyZXR1cm4gby5pfXQ9JC52W3BdCmlmKHQhPW51bGwpcmV0dXJu
-IHQKcz12LmludGVyY2VwdG9yc0J5VGFnW3BdCmlmKHM9PW51bGwpe3A9SC5jKCQudS4kMihhLHApKQpp
-ZihwIT1udWxsKXtvPSQualtwXQppZihvIT1udWxsKXtPYmplY3QuZGVmaW5lUHJvcGVydHkoYSx2LmRp
-c3BhdGNoUHJvcGVydHlOYW1lLHt2YWx1ZTpvLGVudW1lcmFibGU6ZmFsc2Usd3JpdGFibGU6dHJ1ZSxj
-b25maWd1cmFibGU6dHJ1ZX0pCnJldHVybiBvLml9dD0kLnZbcF0KaWYodCE9bnVsbClyZXR1cm4gdApz
-PXYuaW50ZXJjZXB0b3JzQnlUYWdbcF19fWlmKHM9PW51bGwpcmV0dXJuIG51bGwKdD1zLnByb3RvdHlw
-ZQpyPXBbMF0KaWYocj09PSIhIil7bz1ILmwodCkKJC5qW3BdPW8KT2JqZWN0LmRlZmluZVByb3BlcnR5
-KGEsdi5kaXNwYXRjaFByb3BlcnR5TmFtZSx7dmFsdWU6byxlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxl
-OnRydWUsY29uZmlndXJhYmxlOnRydWV9KQpyZXR1cm4gby5pfWlmKHI9PT0ifiIpeyQudltwXT10CnJl
-dHVybiB0fWlmKHI9PT0iLSIpe3E9SC5sKHQpCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShPYmplY3QuZ2V0
-UHJvdG90eXBlT2YoYSksdi5kaXNwYXRjaFByb3BlcnR5TmFtZSx7dmFsdWU6cSxlbnVtZXJhYmxlOmZh
-bHNlLHdyaXRhYmxlOnRydWUsY29uZmlndXJhYmxlOnRydWV9KQpyZXR1cm4gcS5pfWlmKHI9PT0iKyIp
-cmV0dXJuIEguTGMoYSx0KQppZihyPT09IioiKXRocm93IEguYihQLm4ocCkpCmlmKHYubGVhZlRhZ3Nb
-cF09PT10cnVlKXtxPUgubCh0KQpPYmplY3QuZGVmaW5lUHJvcGVydHkoT2JqZWN0LmdldFByb3RvdHlw
-ZU9mKGEpLHYuZGlzcGF0Y2hQcm9wZXJ0eU5hbWUse3ZhbHVlOnEsZW51bWVyYWJsZTpmYWxzZSx3cml0
-YWJsZTp0cnVlLGNvbmZpZ3VyYWJsZTp0cnVlfSkKcmV0dXJuIHEuaX1lbHNlIHJldHVybiBILkxjKGEs
-dCl9LApMYzpmdW5jdGlvbihhLGIpe3ZhciB0PU9iamVjdC5nZXRQcm90b3R5cGVPZihhKQpPYmplY3Qu
-ZGVmaW5lUHJvcGVydHkodCx2LmRpc3BhdGNoUHJvcGVydHlOYW1lLHt2YWx1ZTpKLlF1KGIsdCxudWxs
-LG51bGwpLGVudW1lcmFibGU6ZmFsc2Usd3JpdGFibGU6dHJ1ZSxjb25maWd1cmFibGU6dHJ1ZX0pCnJl
-dHVybiBifSwKbDpmdW5jdGlvbihhKXtyZXR1cm4gSi5RdShhLCExLG51bGwsISFhLiRpWGopfSwKVkY6
-ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PWIucHJvdG90eXBlCmlmKHYubGVhZlRhZ3NbYV09PT10cnVlKXJl
-dHVybiBILmwodCkKZWxzZSByZXR1cm4gSi5RdSh0LGMsbnVsbCxudWxsKX0sCk06ZnVuY3Rpb24oKXtp
-ZighMD09PSQuSylyZXR1cm4KJC5LPSEwCkguRCgpfSwKRDpmdW5jdGlvbigpe3ZhciB0LHMscixxLHAs
-byxuLG0KJC5qPU9iamVjdC5jcmVhdGUobnVsbCkKJC52PU9iamVjdC5jcmVhdGUobnVsbCkKSC5hKCkK
-dD12LmludGVyY2VwdG9yc0J5VGFnCnM9T2JqZWN0LmdldE93blByb3BlcnR5TmFtZXModCkKaWYodHlw
-ZW9mIHdpbmRvdyE9InVuZGVmaW5lZCIpe3dpbmRvdwpyPWZ1bmN0aW9uKCl7fQpmb3IocT0wO3E8cy5s
-ZW5ndGg7KytxKXtwPXNbcV0Kbz0kLng3LiQxKHApCmlmKG8hPW51bGwpe249SC5WRihwLHRbcF0sbykK
-aWYobiE9bnVsbCl7T2JqZWN0LmRlZmluZVByb3BlcnR5KG8sdi5kaXNwYXRjaFByb3BlcnR5TmFtZSx7
-dmFsdWU6bixlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxlOnRydWUsY29uZmlndXJhYmxlOnRydWV9KQpy
-LnByb3RvdHlwZT1vfX19fWZvcihxPTA7cTxzLmxlbmd0aDsrK3Epe3A9c1txXQppZigvXltBLVphLXpf
-XS8udGVzdChwKSl7bT10W3BdCnRbIiEiK3BdPW0KdFsifiIrcF09bQp0WyItIitwXT1tCnRbIisiK3Bd
-PW0KdFsiKiIrcF09bX19fSwKYTpmdW5jdGlvbigpe3ZhciB0LHMscixxLHAsbyxuPUMuTzQoKQpuPUgu
-RihDLllxLEguRihDLktVLEguRihDLmZRLEguRihDLmZRLEguRihDLmk3LEguRihDLnhpLEguRihDLmRr
-KEMud2IpLG4pKSkpKSkpCmlmKHR5cGVvZiBkYXJ0TmF0aXZlRGlzcGF0Y2hIb29rc1RyYW5zZm9ybWVy
-IT0idW5kZWZpbmVkIil7dD1kYXJ0TmF0aXZlRGlzcGF0Y2hIb29rc1RyYW5zZm9ybWVyCmlmKHR5cGVv
-ZiB0PT0iZnVuY3Rpb24iKXQ9W3RdCmlmKHQuY29uc3RydWN0b3I9PUFycmF5KWZvcihzPTA7czx0Lmxl
-bmd0aDsrK3Mpe3I9dFtzXQppZih0eXBlb2Ygcj09ImZ1bmN0aW9uIiluPXIobil8fG59fXE9bi5nZXRU
-YWcKcD1uLmdldFVua25vd25UYWcKbz1uLnByb3RvdHlwZUZvclRhZwokLnk9bmV3IEgucihxKQokLnU9
-bmV3IEguZEMocCkKJC54Nz1uZXcgSC53TihvKX0sCkY6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gYShiKXx8
-Yn0sCnY0OmZ1bmN0aW9uKGEsYixjLGQsZSxmKXt2YXIgdD1iPyJtIjoiIixzPWM/IiI6ImkiLHI9ZD8i
-dSI6IiIscT1lPyJzIjoiIixwPWY/ImciOiIiLG89ZnVuY3Rpb24oZyxoKXt0cnl7cmV0dXJuIG5ldyBS
-ZWdFeHAoZyxoKX1jYXRjaChuKXtyZXR1cm4gbn19KGEsdCtzK3IrcStwKQppZihvIGluc3RhbmNlb2Yg
-UmVnRXhwKXJldHVybiBvCnRocm93IEguYihQLnJyKCJJbGxlZ2FsIFJlZ0V4cCBwYXR0ZXJuICgiK1N0
-cmluZyhvKSsiKSIsYSxudWxsKSl9LAptMjpmdW5jdGlvbihhLGIsYyl7dmFyIHQKaWYodHlwZW9mIGI9
-PSJzdHJpbmciKXJldHVybiBhLmluZGV4T2YoYixjKT49MAplbHNlIGlmKGIgaW5zdGFuY2VvZiBILlZS
-KXt0PUMueEIuRyhhLGMpCnJldHVybiBiLmIudGVzdCh0KX1lbHNle3Q9Si5GTChiLEMueEIuRyhhLGMp
-KQpyZXR1cm4hdC5nbDAodCl9fSwKQTQ6ZnVuY3Rpb24oYSl7aWYoYS5pbmRleE9mKCIkIiwwKT49MCly
-ZXR1cm4gYS5yZXBsYWNlKC9cJC9nLCIkJCQkIikKcmV0dXJuIGF9LAplQTpmdW5jdGlvbihhKXtpZigv
-W1tcXXt9KCkqKz8uXFxeJHxdLy50ZXN0KGEpKXJldHVybiBhLnJlcGxhY2UoL1tbXF17fSgpKis/Llxc
-XiR8XS9nLCJcXCQmIikKcmV0dXJuIGF9LAp5czpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9SC5uTShhLGIs
-YykKcmV0dXJuIHR9LApuTTpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEKaWYoYj09PSIiKXtpZihh
-PT09IiIpcmV0dXJuIGMKdD1hLmxlbmd0aApmb3Iocz1jLHI9MDtyPHQ7KytyKXM9cythW3JdK2MKcmV0
-dXJuIHMuY2hhckNvZGVBdCgwKT09MD9zOnN9cT1hLmluZGV4T2YoYiwwKQppZihxPDApcmV0dXJuIGEK
-aWYoYS5sZW5ndGg8NTAwfHxjLmluZGV4T2YoIiQiLDApPj0wKXJldHVybiBhLnNwbGl0KGIpLmpvaW4o
-YykKcmV0dXJuIGEucmVwbGFjZShuZXcgUmVnRXhwKEguZUEoYiksJ2cnKSxILkE0KGMpKX0sClBEOmZ1
-bmN0aW9uIFBEKGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9Yn0sCldVOmZ1bmN0aW9uIFdVKCl7fSwKTFA6
-ZnVuY3Rpb24gTFAoYSxiLGMsZCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLiR0aT1kfSwK
-WFI6ZnVuY3Rpb24gWFIoYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKTEk6ZnVuY3Rpb24gTEkoYSxi
-LGMsZCxlKXt2YXIgXz10aGlzCl8uYT1hCl8uYz1iCl8uZD1jCl8uZT1kCl8uZj1lfSwKQ2o6ZnVuY3Rp
-b24gQ2ooYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKZjk6ZnVuY3Rpb24gZjkoYSxi
-LGMsZCxlLGYpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWQKXy5lPWUKXy5mPWZ9LApX
-MDpmdW5jdGlvbiBXMChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKYXo6ZnVuY3Rpb24gYXooYSxiLGMp
-e3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKdlY6ZnVuY3Rpb24gdlYoYSl7dGhpcy5hPWF9LApi
-cTpmdW5jdGlvbiBicShhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKQW06ZnVuY3Rpb24gQW0oYSl7dGhp
-cy5hPWF9LApYTzpmdW5jdGlvbiBYTyhhKXt0aGlzLmE9YQp0aGlzLmI9bnVsbH0sClRwOmZ1bmN0aW9u
-IFRwKCl7fSwKbGM6ZnVuY3Rpb24gbGMoKXt9LAp6eDpmdW5jdGlvbiB6eCgpe30sCmp5OmZ1bmN0aW9u
-IGp5KGEsYixjLGQpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWR9LApFcTpmdW5jdGlv
-biBFcShhKXt0aGlzLmE9YX0sCmtZOmZ1bmN0aW9uIGtZKGEpe3RoaXMuYT1hfSwKTjU6ZnVuY3Rpb24g
-TjUoYSl7dmFyIF89dGhpcwpfLmE9MApfLmY9Xy5lPV8uZD1fLmM9Xy5iPW51bGwKXy5yPTAKXy4kdGk9
-YX0sCmRiOmZ1bmN0aW9uIGRiKGEsYil7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmQ9Xy5jPW51bGx9
-LAppNTpmdW5jdGlvbiBpNShhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApONjpmdW5jdGlvbiBONihh
-LGIsYyl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmQ9Xy5jPW51bGwKXy4kdGk9Y30sCnI6ZnVuY3Rp
-b24gcihhKXt0aGlzLmE9YX0sCmRDOmZ1bmN0aW9uIGRDKGEpe3RoaXMuYT1hfSwKd046ZnVuY3Rpb24g
-d04oYSl7dGhpcy5hPWF9LApWUjpmdW5jdGlvbiBWUihhLGIpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIK
-Xy5kPV8uYz1udWxsfSwKRUs6ZnVuY3Rpb24gRUsoYSl7dGhpcy5iPWF9LApLVzpmdW5jdGlvbiBLVyhh
-LGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApQYjpmdW5jdGlvbiBQYihhLGIsYyl7dmFy
-IF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9bnVsbH0sCnRROmZ1bmN0aW9uIHRRKGEsYil7dGhp
-cy5hPWEKdGhpcy5jPWJ9LApORjpmdW5jdGlvbiBORihhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhp
-cy5jPWN9LApTZDpmdW5jdGlvbiBTZChhLGIsYyl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9Ywpf
-LmQ9bnVsbH0sClhGOmZ1bmN0aW9uKGEpe3JldHVybiBhfSwKb2Q6ZnVuY3Rpb24oYSxiLGMpe2lmKGE+
-Pj4wIT09YXx8YT49Yyl0aHJvdyBILmIoSC5IWShiLGEpKX0sCnJNOmZ1bmN0aW9uKGEsYixjKXt2YXIg
-dAppZighKGE+Pj4wIT09YSkpdD1iPj4+MCE9PWJ8fGE+Ynx8Yj5jCmVsc2UgdD0hMAppZih0KXRocm93
-IEguYihILmF1KGEsYixjKSkKcmV0dXJuIGJ9LApwRjpmdW5jdGlvbiBwRigpe30sCmIwOmZ1bmN0aW9u
-IGIwKCl7fSwKRGc6ZnVuY3Rpb24gRGcoKXt9LApQZzpmdW5jdGlvbiBQZygpe30sCnhqOmZ1bmN0aW9u
-IHhqKCl7fSwKZEU6ZnVuY3Rpb24gZEUoKXt9LApaQTpmdW5jdGlvbiBaQSgpe30sCndmOmZ1bmN0aW9u
-IHdmKCl7fSwKUHE6ZnVuY3Rpb24gUHEoKXt9LAplRTpmdW5jdGlvbiBlRSgpe30sClY2OmZ1bmN0aW9u
-IFY2KCl7fSwKUkc6ZnVuY3Rpb24gUkcoKXt9LApWUDpmdW5jdGlvbiBWUCgpe30sCldCOmZ1bmN0aW9u
-IFdCKCl7fSwKWkc6ZnVuY3Rpb24gWkcoKXt9LApjejpmdW5jdGlvbihhLGIpe3ZhciB0PWIuYwpyZXR1
-cm4gdD09bnVsbD9iLmM9SC5CYyhhLGIueiwhMCk6dH0sCnhaOmZ1bmN0aW9uKGEsYil7dmFyIHQ9Yi5j
-CnJldHVybiB0PT1udWxsP2IuYz1ILlEyKGEsImI4IixbYi56XSk6dH0sClExOmZ1bmN0aW9uKGEpe3Zh
-ciB0PWEueQppZih0PT09Nnx8dD09PTd8fHQ9PT04KXJldHVybiBILlExKGEueikKcmV0dXJuIHQ9PT0x
-MXx8dD09PTEyfSwKbUQ6ZnVuY3Rpb24oYSl7dmFyIHQ9YS5jeQp0LnRvU3RyaW5nCnJldHVybiB0fSwK
-TjA6ZnVuY3Rpb24oYSl7cmV0dXJuIEguRSh2LnR5cGVVbml2ZXJzZSxhLCExKX0sClBMOmZ1bmN0aW9u
-KGEsYixjLGEwKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGksaCxnLGYsZSxkPWIueQpzd2l0Y2go
-ZCl7Y2FzZSA1OmNhc2UgMTpjYXNlIDI6Y2FzZSAzOmNhc2UgNDpyZXR1cm4gYgpjYXNlIDY6dD1iLnoK
-cz1ILlBMKGEsdCxjLGEwKQppZihzPT09dClyZXR1cm4gYgpyZXR1cm4gSC5TTyhhLHMsITApCmNhc2Ug
-Nzp0PWIuegpzPUguUEwoYSx0LGMsYTApCmlmKHM9PT10KXJldHVybiBiCnJldHVybiBILkJjKGEscywh
-MCkKY2FzZSA4OnQ9Yi56CnM9SC5QTChhLHQsYyxhMCkKaWYocz09PXQpcmV0dXJuIGIKcmV0dXJuIEgu
-TE4oYSxzLCEwKQpjYXNlIDk6cj1iLlEKcT1ILmJaKGEscixjLGEwKQppZihxPT09cilyZXR1cm4gYgpy
-ZXR1cm4gSC5RMihhLGIueixxKQpjYXNlIDEwOnA9Yi56Cm89SC5QTChhLHAsYyxhMCkKbj1iLlEKbT1I
-LmJaKGEsbixjLGEwKQppZihvPT09cCYmbT09PW4pcmV0dXJuIGIKcmV0dXJuIEguYXAoYSxvLG0pCmNh
-c2UgMTE6bD1iLnoKaz1ILlBMKGEsbCxjLGEwKQpqPWIuUQppPUgucVQoYSxqLGMsYTApCmlmKGs9PT1s
-JiZpPT09ailyZXR1cm4gYgpyZXR1cm4gSC5OZihhLGssaSkKY2FzZSAxMjpoPWIuUQphMCs9aC5sZW5n
-dGgKZz1ILmJaKGEsaCxjLGEwKQpwPWIuegpvPUguUEwoYSxwLGMsYTApCmlmKGc9PT1oJiZvPT09cCly
-ZXR1cm4gYgpyZXR1cm4gSC5EUyhhLG8sZywhMCkKY2FzZSAxMzpmPWIuegppZihmPGEwKXJldHVybiBi
-CmU9Y1tmLWEwXQppZihlPT1udWxsKXJldHVybiBiCnJldHVybiBlCmRlZmF1bHQ6dGhyb3cgSC5iKFAu
-aFYoIkF0dGVtcHRlZCB0byBzdWJzdGl0dXRlIHVuZXhwZWN0ZWQgUlRJIGtpbmQgIitkKSl9fSwKYlo6
-ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyLHEscD1iLmxlbmd0aCxvPVtdCmZvcih0PSExLHM9MDtz
-PHA7KytzKXtyPWJbc10KcT1ILlBMKGEscixjLGQpCmlmKHEhPT1yKXQ9ITAKby5wdXNoKHEpfXJldHVy
-biB0P286Yn0sCnZPOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMscixxLHAsbz1iLmxlbmd0aCxuPVtd
-CmZvcih0PSExLHM9MDtzPG87cys9Mil7cj1iW3NdCnE9YltzKzFdCnA9SC5QTChhLHEsYyxkKQppZihw
-IT09cSl0PSEwCm4ucHVzaChyKQpuLnB1c2gocCl9cmV0dXJuIHQ/bjpifSwKcVQ6ZnVuY3Rpb24oYSxi
-LGMsZCl7dmFyIHQscz1iLmEscj1ILmJaKGEscyxjLGQpLHE9Yi5iLHA9SC5iWihhLHEsYyxkKSxvPWIu
-YyxuPUgudk8oYSxvLGMsZCkKaWYocj09PXMmJnA9PT1xJiZuPT09bylyZXR1cm4gYgp0PW5ldyBILkVU
-KCkKdC5hPXIKdC5iPXAKdC5jPW4KcmV0dXJuIHR9LApKUzpmdW5jdGlvbihhKXt2YXIgdD1hLiRTCmlm
-KHQhPW51bGwpe2lmKHR5cGVvZiB0PT0ibnVtYmVyIilyZXR1cm4gSC5CcCh0KQpyZXR1cm4gYS4kUygp
-fXJldHVybiBudWxsfSwKVWU6ZnVuY3Rpb24oYSxiKXt2YXIgdAppZihILlExKGIpKWlmKGEgaW5zdGFu
-Y2VvZiBILlRwKXt0PUguSlMoYSkKaWYodCE9bnVsbClyZXR1cm4gdH1yZXR1cm4gSC5xKGEpfSwKcTpm
-dW5jdGlvbihhKXt2YXIgdAppZihhIGluc3RhbmNlb2YgUC5NaCl7dD1hLiR0aQpyZXR1cm4gdCE9bnVs
-bD90OkguVlUoYSl9aWYoQXJyYXkuaXNBcnJheShhKSlyZXR1cm4gSC50NihhKQpyZXR1cm4gSC5WVShK
-LmlhKGEpKX0sCnQ2OmZ1bmN0aW9uKGEpe3ZhciB0PWFbdi5hcnJheVJ0aV0scz11LnYKaWYodD09bnVs
-bClyZXR1cm4gcwppZih0LmNvbnN0cnVjdG9yIT09cy5jb25zdHJ1Y3RvcilyZXR1cm4gcwpyZXR1cm4g
-dH0sCkxoOmZ1bmN0aW9uKGEpe3ZhciB0PWEuJHRpCnJldHVybiB0IT1udWxsP3Q6SC5WVShhKX0sClZV
-OmZ1bmN0aW9uKGEpe3ZhciB0PWEuY29uc3RydWN0b3Iscz10LiRjY2FjaGUKaWYocyE9bnVsbClyZXR1
-cm4gcwpyZXR1cm4gSC5yOShhLHQpfSwKcjk6ZnVuY3Rpb24oYSxiKXt2YXIgdD1hIGluc3RhbmNlb2Yg
-SC5UcD9hLl9fcHJvdG9fXy5fX3Byb3RvX18uY29uc3RydWN0b3I6YixzPUguYWkodi50eXBlVW5pdmVy
-c2UsdC5uYW1lKQpiLiRjY2FjaGU9cwpyZXR1cm4gc30sCkJwOmZ1bmN0aW9uKGEpe3ZhciB0LHM9YSxy
-PXYudHlwZXMscT1yW3NdCmlmKHR5cGVvZiBxPT0ic3RyaW5nIil7dD1ILkUodi50eXBlVW5pdmVyc2Us
-cSwhMSkKcltzXT10CnJldHVybiB0fXJldHVybiBxfSwKSko6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcyxz
-PUguWU8scj11LksKaWYodD09PXIpe3M9SC5rZQp0LmE9SC5UaX1lbHNlIGlmKEguQTgodCl8fHQ9PT1y
-KXtzPUguSXcKdC5hPUguaG59ZWxzZSBpZih0PT09dS5xKXM9SC5vawplbHNlIGlmKHQ9PT11LmdSKXM9
-SC5LSAplbHNlIGlmKHQ9PT11LmRpKXM9SC5LSAplbHNlIGlmKHQ9PT11Lk4pcz1ILk1NCmVsc2UgaWYo
-dD09PXUueSlzPUguclEKZWxzZSBpZih0Lnk9PT05KXtyPXQuegppZih0LlEuZXZlcnkoSC5jYykpe3Qu
-cj0iJGkiK3IKcz1ILnQ0fX10LmI9cwpyZXR1cm4gdC5iKGEpfSwKWU86ZnVuY3Rpb24oYSl7dmFyIHQ9
-dGhpcwpyZXR1cm4gSC5XZSh2LnR5cGVVbml2ZXJzZSxILlVlKGEsdCksbnVsbCx0LG51bGwpfSwKdDQ6
-ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcwp0PXQucgp0LnRvU3RyaW5nCmlmKGEgaW5zdGFuY2VvZiBQLk1o
-KXJldHVybiEhYVt0XQpyZXR1cm4hIUouaWEoYSlbdF19LApPejpmdW5jdGlvbihhKXt2YXIgdD10aGlz
-CmlmKGE9PW51bGwpcmV0dXJuIGEKZWxzZSBpZih0LmIoYSkpcmV0dXJuIGEKdGhyb3cgSC5iKEguWmMo
-SC5wKGEsSC5VZShhLHQpLEguSih0LG51bGwpKSkpfSwKRGg6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQ9
-bnVsbAppZihILldlKHYudHlwZVVuaXZlcnNlLGEsdCxiLHQpKXJldHVybiBhCnRocm93IEguYihILlpj
-KCJUaGUgdHlwZSBhcmd1bWVudCAnIitILmQoSC5KKGEsdCkpKyInIGlzIG5vdCBhIHN1YnR5cGUgb2Yg
-dGhlIHR5cGUgdmFyaWFibGUgYm91bmQgJyIrSC5kKEguSihiLHQpKSsiJyBvZiB0eXBlIHZhcmlhYmxl
-ICciK2MrIicgaW4gJyIrSC5kKGQpKyInLiIpKX0sCnA6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PVAuaChh
-KSxzPUguSihiPT1udWxsP0gucShhKTpiLG51bGwpCnJldHVybiB0KyI6IHR5cGUgJyIrSC5kKHMpKyIn
-IGlzIG5vdCBhIHN1YnR5cGUgb2YgdHlwZSAnIitILmQoYykrIicifSwKWmM6ZnVuY3Rpb24oYSl7cmV0
-dXJuIG5ldyBILngoIlR5cGVFcnJvcjogIithKX0sCkI6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IEgu
-eCgiVHlwZUVycm9yOiAiK0gucChhLG51bGwsYikpfSwKa2U6ZnVuY3Rpb24oYSl7cmV0dXJuITB9LApU
-aTpmdW5jdGlvbihhKXtyZXR1cm4gYX0sCkl3OmZ1bmN0aW9uKGEpe3JldHVybiEwfSwKaG46ZnVuY3Rp
-b24oYSl7cmV0dXJuIGF9LApyUTpmdW5jdGlvbihhKXtyZXR1cm4hMD09PWF8fCExPT09YX0sCkU5OmZ1
-bmN0aW9uKGEpe2lmKCEwPT09YXx8ITE9PT1hKXJldHVybiBhCmlmKGE9PW51bGwpcmV0dXJuIGEKdGhy
-b3cgSC5iKEguQihhLCJib29sIikpfSwKZGo6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJudW1iZXIi
-KXJldHVybiBhCmlmKGE9PW51bGwpcmV0dXJuIGEKdGhyb3cgSC5iKEguQihhLCJkb3VibGUiKSl9LApv
-azpmdW5jdGlvbihhKXtyZXR1cm4gdHlwZW9mIGE9PSJudW1iZXIiJiZNYXRoLmZsb29yKGEpPT09YX0s
-CldZOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIiYmTWF0aC5mbG9vcihhKT09PWEpcmV0
-dXJuIGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJvdyBILmIoSC5CKGEsImludCIpKX0sCktIOmZ1bmN0
-aW9uKGEpe3JldHVybiB0eXBlb2YgYT09Im51bWJlciJ9LAp1VTpmdW5jdGlvbihhKXtpZih0eXBlb2Yg
-YT09Im51bWJlciIpcmV0dXJuIGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJvdyBILmIoSC5CKGEsIm51
-bSIpKX0sCk1NOmZ1bmN0aW9uKGEpe3JldHVybiB0eXBlb2YgYT09InN0cmluZyJ9LApjOmZ1bmN0aW9u
-KGEpe2lmKHR5cGVvZiBhPT0ic3RyaW5nIilyZXR1cm4gYQppZihhPT1udWxsKXJldHVybiBhCnRocm93
-IEguYihILkIoYSwiU3RyaW5nIikpfSwKdzpmdW5jdGlvbihhLGIpe3ZhciB0LHMscgpmb3IodD0iIixz
-PSIiLHI9MDtyPGEubGVuZ3RoOysrcixzPSIsICIpdCs9Qy54Qi5oKHMsSC5KKGFbcl0sYikpCnJldHVy
-biB0fSwKZjpmdW5jdGlvbihhMSxhMixhMyl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixpLGgsZyxm
-LGUsZCxjLGIsYSxhMD0iLCAiCmlmKGEzIT1udWxsKXt0PWEzLmxlbmd0aAppZihhMj09bnVsbCl7YTI9
-SC5WTShbXSx1LnMpCnM9bnVsbH1lbHNlIHM9YTIubGVuZ3RoCnI9YTIubGVuZ3RoCmZvcihxPXQ7cT4w
-Oy0tcSlDLk5tLmkoYTIsIlQiKyhyK3EpKQpmb3IocD11Lkssbz0iPCIsbj0iIixxPTA7cTx0OysrcSxu
-PWEwKXtvKz1uCm09YTIubGVuZ3RoCmw9bS0xLXEKaWYobDwwKXJldHVybiBILmsoYTIsbCkKbz1DLnhC
-LmgobyxhMltsXSkKaz1hM1txXQppZighKEguQTgoayl8fGs9PT1wKSltPSEoaz09PXApCmVsc2UgbT0h
-MQppZihtKW8rPUMueEIuaCgiIGV4dGVuZHMgIixILkooayxhMikpfW8rPSI+In1lbHNle289IiIKcz1u
-dWxsfXA9YTEuegpqPWExLlEKaT1qLmEKaD1pLmxlbmd0aApnPWouYgpmPWcubGVuZ3RoCmU9ai5jCmQ9
-ZS5sZW5ndGgKYz1ILkoocCxhMikKZm9yKGI9IiIsYT0iIixxPTA7cTxoOysrcSxhPWEwKWIrPUMueEIu
-aChhLEguSihpW3FdLGEyKSkKaWYoZj4wKXtiKz1hKyJbIgpmb3IoYT0iIixxPTA7cTxmOysrcSxhPWEw
-KWIrPUMueEIuaChhLEguSihnW3FdLGEyKSkKYis9Il0ifWlmKGQ+MCl7Yis9YSsieyIKZm9yKGE9IiIs
-cT0wO3E8ZDtxKz0yLGE9YTApYis9Qy54Qi5oKGEsSC5KKGVbcSsxXSxhMikpKyIgIitlW3FdCmIrPSJ9
-In1pZihzIT1udWxsKXthMi50b1N0cmluZwphMi5sZW5ndGg9c31yZXR1cm4gbysiKCIrYisiKSA9PiAi
-K0guZChjKX0sCko6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG8sbixtPWEueQppZihtPT09NSly
-ZXR1cm4iZXJhc2VkIgppZihtPT09MilyZXR1cm4iZHluYW1pYyIKaWYobT09PTMpcmV0dXJuInZvaWQi
-CmlmKG09PT0xKXJldHVybiJOZXZlciIKaWYobT09PTQpcmV0dXJuImFueSIKaWYobT09PTYpe3Q9SC5K
-KGEueixiKQpyZXR1cm4gdH1pZihtPT09Nyl7cz1hLnoKdD1ILkoocyxiKQpyPXMueQpyZXR1cm4gSi5t
-KHI9PT0xMXx8cj09PTEyP0MueEIuaCgiKCIsdCkrIikiOnQsIj8iKX1pZihtPT09OClyZXR1cm4iRnV0
-dXJlT3I8IitILmQoSC5KKGEueixiKSkrIj4iCmlmKG09PT05KXtxPUguQyhhLnopCnA9YS5RCnJldHVy
-biBwLmxlbmd0aCE9PTA/cSsoIjwiK0gudyhwLGIpKyI+Iik6cX1pZihtPT09MTEpcmV0dXJuIEguZihh
-LGIsbnVsbCkKaWYobT09PTEyKXJldHVybiBILmYoYS56LGIsYS5RKQppZihtPT09MTMpe2IudG9TdHJp
-bmcKbz1hLnoKbj1iLmxlbmd0aApvPW4tMS1vCmlmKG88MHx8bz49bilyZXR1cm4gSC5rKGIsbykKcmV0
-dXJuIGJbb119cmV0dXJuIj8ifSwKQzpmdW5jdGlvbihhKXt2YXIgdCxzPUguSmcoYSkKaWYocyE9bnVs
-bClyZXR1cm4gcwp0PSJtaW5pZmllZDoiK2EKcmV0dXJuIHR9LApRbzpmdW5jdGlvbihhLGIpe3ZhciB0
-PWEudFJbYl0KZm9yKDt0eXBlb2YgdD09InN0cmluZyI7KXQ9YS50Ult0XQpyZXR1cm4gdH0sCmFpOmZ1
-bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvPWEuZVQsbj1vW2JdCmlmKG49PW51bGwpcmV0dXJuIEgu
-RShhLGIsITEpCmVsc2UgaWYodHlwZW9mIG49PSJudW1iZXIiKXt0PW4Kcz1ILm1aKGEsNSwiIyIpCnI9
-W10KZm9yKHE9MDtxPHQ7KytxKXIucHVzaChzKQpwPUguUTIoYSxiLHIpCm9bYl09cApyZXR1cm4gcH1l
-bHNlIHJldHVybiBufSwKeGI6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSC5JeChhLnRSLGIpfSwKRkY6ZnVu
-Y3Rpb24oYSxiKXtyZXR1cm4gSC5JeChhLmVULGIpfSwKRTpmdW5jdGlvbihhLGIsYyl7dmFyIHQscz1h
-LmVDLHI9cy5nZXQoYikKaWYociE9bnVsbClyZXR1cm4gcgp0PUgueihhLG51bGwsYixjKQpzLnNldChi
-LHQpCnJldHVybiB0fSwKY0U6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscj1iLmNoCmlmKHI9PW51bGwp
-cj1iLmNoPW5ldyBNYXAoKQp0PXIuZ2V0KGMpCmlmKHQhPW51bGwpcmV0dXJuIHQKcz1ILnooYSxiLGMs
-ITApCnIuc2V0KGMscykKcmV0dXJuIHN9LAp2NTpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEscD1i
-LmN4CmlmKHA9PW51bGwpcD1iLmN4PW5ldyBNYXAoKQp0PWMuY3kKdC50b1N0cmluZwpzPXQKcj1wLmdl
-dChzKQppZihyIT1udWxsKXJldHVybiByCnE9SC5hcChhLGIsYy55PT09MTA/Yy5ROltjXSkKcC5zZXQo
-cyxxKQpyZXR1cm4gcX0sCno6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQ9SC5pKEgubyhhLGIsYyxkKSkK
-aWYodCE9bnVsbClyZXR1cm4gdAp0aHJvdyBILmIoUC5uKCdfVW5pdmVyc2UuX3BhcnNlUmVjaXBlKCIn
-K0guZChjKSsnIiknKSl9LApCRDpmdW5jdGlvbihhLGIpe2IuYT1ILk96CmIuYj1ILkpKCnJldHVybiBi
-fSwKbVo6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscj1hLmVDLmdldChjKQppZihyIT1udWxsKXJldHVy
-biByCnQ9bmV3IEguSmMobnVsbCxudWxsKQp0Lnk9Ygp0LmN5PWMKcz1ILkJEKGEsdCkKYS5lQy5zZXQo
-YyxzKQpyZXR1cm4gc30sClNPOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHI9Yi5jeQpyLnRvU3RyaW5n
-CnQ9cisiKiIKcz1hLmVDLmdldCh0KQppZihzIT1udWxsKXJldHVybiBzCnI9SC5aNyhhLGIsdCxjKQph
-LmVDLnNldCh0LHIpCnJldHVybiByfSwKWjc6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscwppZihkKXt0
-PWIueQppZihILkE4KGIpfHxiPT09dS5LfHxiPT09dS5QfHx0PT09N3x8dD09PTYpcmV0dXJuIGJ9cz1u
-ZXcgSC5KYyhudWxsLG51bGwpCnMueT02CnMuej1iCnMuY3k9YwpyZXR1cm4gSC5CRChhLHMpfSwKQmM6
-ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscj1iLmN5CnIudG9TdHJpbmcKdD1yKyI/IgpzPWEuZUMuZ2V0
-KHQpCmlmKHMhPW51bGwpcmV0dXJuIHMKcj1ILmxsKGEsYix0LGMpCmEuZUMuc2V0KHQscikKcmV0dXJu
-IHJ9LApsbDpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxzLHIscQppZihkKXt0PWIueQppZighSC5BOChi
-KSlpZighKGI9PT11LlApKWlmKHQhPT03KXM9dD09PTgmJkgubFIoYi56KQplbHNlIHM9ITAKZWxzZSBz
-PSEwCmVsc2Ugcz0hMAppZihzKXJldHVybiBiCmVsc2UgaWYodD09PTF8fGI9PT11LmF3KXJldHVybiB1
-LlAKZWxzZSBpZih0PT09Nil7cj1iLnoKaWYoci55PT09OCYmSC5sUihyLnopKXJldHVybiByCmVsc2Ug
-cmV0dXJuIEguY3ooYSxiKX19cT1uZXcgSC5KYyhudWxsLG51bGwpCnEueT03CnEuej1iCnEuY3k9Ywpy
-ZXR1cm4gSC5CRChhLHEpfSwKTE46ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscj1iLmN5CnIudG9TdHJp
-bmcKdD1yKyIvIgpzPWEuZUMuZ2V0KHQpCmlmKHMhPW51bGwpcmV0dXJuIHMKcj1ILmVWKGEsYix0LGMp
-CmEuZUMuc2V0KHQscikKcmV0dXJuIHJ9LAplVjpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxzCmlmKGQp
-e3Q9Yi55CmlmKEguQTgoYil8fGI9PT11Lkt8fGI9PT11LkspcmV0dXJuIGIKZWxzZSBpZih0PT09MSly
-ZXR1cm4gSC5RMihhLCJiOCIsW2JdKQplbHNlIGlmKGI9PT11LlApcmV0dXJuIHUuYVF9cz1uZXcgSC5K
-YyhudWxsLG51bGwpCnMueT04CnMuej1iCnMuY3k9YwpyZXR1cm4gSC5CRChhLHMpfSwKSGM6ZnVuY3Rp
-b24oYSxiKXt2YXIgdCxzLHI9IiIrYisiXiIscT1hLmVDLmdldChyKQppZihxIT1udWxsKXJldHVybiBx
-CnQ9bmV3IEguSmMobnVsbCxudWxsKQp0Lnk9MTMKdC56PWIKdC5jeT1yCnM9SC5CRChhLHQpCmEuZUMu
-c2V0KHIscykKcmV0dXJuIHN9LApVeDpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwPWEubGVuZ3RoCmZv
-cih0PSIiLHM9IiIscj0wO3I8cDsrK3Iscz0iLCIpe3E9YVtyXS5jeQpxLnRvU3RyaW5nCnQrPXMrcX1y
-ZXR1cm4gdH0sClM0OmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAsbz1hLmxlbmd0aApmb3IodD0iIixz
-PSIiLHI9MDtyPG87cis9MixzPSIsIil7cT1hW3JdCnA9YVtyKzFdLmN5CnAudG9TdHJpbmcKdCs9cytx
-KyI6IitwfXJldHVybiB0fSwKUTI6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxPWIKaWYoYy5sZW5n
-dGghPT0wKXErPSI8IitILlV4KGMpKyI+Igp0PWEuZUMuZ2V0KHEpCmlmKHQhPW51bGwpcmV0dXJuIHQK
-cz1uZXcgSC5KYyhudWxsLG51bGwpCnMueT05CnMuej1iCnMuUT1jCmlmKGMubGVuZ3RoPjApcy5jPWNb
-MF0Kcy5jeT1xCnI9SC5CRChhLHMpCmEuZUMuc2V0KHEscikKcmV0dXJuIHJ9LAphcDpmdW5jdGlvbihh
-LGIsYyl7dmFyIHQscyxyLHEscCxvCmlmKGIueT09PTEwKXt0PWIuegpzPWIuUS5jb25jYXQoYyl9ZWxz
-ZXtzPWMKdD1ifXI9dC5jeQpyLnRvU3RyaW5nCnE9cisiOyIrKCI8IitILlV4KHMpKyI+IikKcD1hLmVD
-LmdldChxKQppZihwIT1udWxsKXJldHVybiBwCm89bmV3IEguSmMobnVsbCxudWxsKQpvLnk9MTAKby56
-PXQKby5RPXMKby5jeT1xCnI9SC5CRChhLG8pCmEuZUMuc2V0KHEscikKcmV0dXJuIHJ9LApOZjpmdW5j
-dGlvbihhLGIsYyl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaj1iLmN5CmoudG9TdHJpbmcKdD1jLmEK
-cz10Lmxlbmd0aApyPWMuYgpxPXIubGVuZ3RoCnA9Yy5jCm89cC5sZW5ndGgKbj0iKCIrSC5VeCh0KQpp
-ZihxPjApbis9KHM+MD8iLCI6IiIpKyJbIitILlV4KHIpKyJdIgppZihvPjApbis9KHM+MD8iLCI6IiIp
-KyJ7IitILlM0KHApKyJ9IgptPWorKG4rIikiKQpsPWEuZUMuZ2V0KG0pCmlmKGwhPW51bGwpcmV0dXJu
-IGwKaz1uZXcgSC5KYyhudWxsLG51bGwpCmsueT0xMQprLno9YgprLlE9YwprLmN5PW0Kaj1ILkJEKGEs
-aykKYS5lQy5zZXQobSxqKQpyZXR1cm4gan0sCkRTOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMscj1i
-LmN5CnIudG9TdHJpbmcKdD1yKyI8IitILlV4KGMpKyI+IgpzPWEuZUMuZ2V0KHQpCmlmKHMhPW51bGwp
-cmV0dXJuIHMKcj1ILmh3KGEsYixjLHQsZCkKYS5lQy5zZXQodCxyKQpyZXR1cm4gcn0sCmh3OmZ1bmN0
-aW9uKGEsYixjLGQsZSl7dmFyIHQscyxyLHEscCxvLG4sbQppZihlKXt0PWMubGVuZ3RoCnM9bmV3IEFy
-cmF5KHQpCmZvcihyPTAscT0wO3E8dDsrK3Epe3A9Y1txXQppZihwLnk9PT0xKXtzW3FdPXA7KytyfX1p
-ZihyPjApe289SC5QTChhLGIscywwKQpuPUguYlooYSxjLHMsMCkKcmV0dXJuIEguRFMoYSxvLG4sYyE9
-PW4pfX1tPW5ldyBILkpjKG51bGwsbnVsbCkKbS55PTEyCm0uej1iCm0uUT1jCm0uY3k9ZApyZXR1cm4g
-SC5CRChhLG0pfSwKbzpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm57dTphLGU6YixyOmMsczpbXSxwOjAs
-bjpkfX0sCmk6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixpLGg9YS5yLGc9YS5z
-CmZvcih0PWgubGVuZ3RoLHM9MDtzPHQ7KXtyPWguY2hhckNvZGVBdChzKQppZihyPj00OCYmcjw9NTcp
-cz1ILkFsKHMrMSxyLGgsZykKZWxzZSBpZigoKChyfDMyKT4+PjApLTk3JjY1NTM1KTwyNnx8cj09PTk1
-fHxyPT09MzYpcz1ILlI4KGEscyxoLGcsITEpCmVsc2UgaWYocj09PTQ2KXM9SC5SOChhLHMsaCxnLCEw
-KQplbHNleysrcwpzd2l0Y2gocil7Y2FzZSA0NDpicmVhawpjYXNlIDU4OmJyZWFrCmNhc2UgNTk6Zy5w
-dXNoKEguS1EoYS51LGEuZSxnLnBvcCgpKSkKYnJlYWsKY2FzZSA5NDpnLnB1c2goSC5IYyhhLnUsZy5w
-b3AoKSkpCmJyZWFrCmNhc2UgMzU6Zy5wdXNoKEgubVooYS51LDUsIiMiKSkKYnJlYWsKY2FzZSA2NDpn
-LnB1c2goSC5tWihhLnUsMiwiQCIpKQpicmVhawpjYXNlIDEyNjpnLnB1c2goSC5tWihhLnUsMywifiIp
-KQpicmVhawpjYXNlIDYwOmcucHVzaChhLnApCmEucD1nLmxlbmd0aApicmVhawpjYXNlIDYyOnE9YS51
-CnA9Zy5zcGxpY2UoYS5wKQpILnJUKGEudSxhLmUscCkKYS5wPWcucG9wKCkKbz1nLnBvcCgpCmlmKHR5
-cGVvZiBvPT0ic3RyaW5nIilnLnB1c2goSC5RMihxLG8scCkpCmVsc2V7bj1ILktRKHEsYS5lLG8pCnN3
-aXRjaChuLnkpe2Nhc2UgMTE6Zy5wdXNoKEguRFMocSxuLHAsYS5uKSkKYnJlYWsKZGVmYXVsdDpnLnB1
-c2goSC5hcChxLG4scCkpCmJyZWFrfX1icmVhawpjYXNlIDM4OkguSTMoYSxnKQpicmVhawpjYXNlIDQy
-Om09YS51CmcucHVzaChILlNPKG0sSC5LUShtLGEuZSxnLnBvcCgpKSxhLm4pKQpicmVhawpjYXNlIDYz
-Om09YS51CmcucHVzaChILkJjKG0sSC5LUShtLGEuZSxnLnBvcCgpKSxhLm4pKQpicmVhawpjYXNlIDQ3
-Om09YS51CmcucHVzaChILkxOKG0sSC5LUShtLGEuZSxnLnBvcCgpKSxhLm4pKQpicmVhawpjYXNlIDQw
-OmcucHVzaChhLnApCmEucD1nLmxlbmd0aApicmVhawpjYXNlIDQxOnE9YS51Cmw9bmV3IEguRVQoKQpr
-PXEuc0VBCmo9cS5zRUEKbz1nLnBvcCgpCmlmKHR5cGVvZiBvPT0ibnVtYmVyIilzd2l0Y2gobyl7Y2Fz
-ZS0xOms9Zy5wb3AoKQpicmVhawpjYXNlLTI6aj1nLnBvcCgpCmJyZWFrCmRlZmF1bHQ6Zy5wdXNoKG8p
-CmJyZWFrfWVsc2UgZy5wdXNoKG8pCnA9Zy5zcGxpY2UoYS5wKQpILnJUKGEudSxhLmUscCkKYS5wPWcu
-cG9wKCkKbC5hPXAKbC5iPWsKbC5jPWoKZy5wdXNoKEguTmYocSxILktRKHEsYS5lLGcucG9wKCkpLGwp
-KQpicmVhawpjYXNlIDkxOmcucHVzaChhLnApCmEucD1nLmxlbmd0aApicmVhawpjYXNlIDkzOnA9Zy5z
-cGxpY2UoYS5wKQpILnJUKGEudSxhLmUscCkKYS5wPWcucG9wKCkKZy5wdXNoKHApCmcucHVzaCgtMSkK
-YnJlYWsKY2FzZSAxMjM6Zy5wdXNoKGEucCkKYS5wPWcubGVuZ3RoCmJyZWFrCmNhc2UgMTI1OnA9Zy5z
-cGxpY2UoYS5wKQpILldTKGEudSxhLmUscCkKYS5wPWcucG9wKCkKZy5wdXNoKHApCmcucHVzaCgtMikK
-YnJlYWsKZGVmYXVsdDp0aHJvdyJCYWQgY2hhcmFjdGVyICIrcn19fWk9Zy5wb3AoKQpyZXR1cm4gSC5L
-UShhLnUsYS5lLGkpfSwKQWw6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyPWItNDgKZm9yKHQ9Yy5s
-ZW5ndGg7YTx0OysrYSl7cz1jLmNoYXJDb2RlQXQoYSkKaWYoIShzPj00OCYmczw9NTcpKWJyZWFrCnI9
-cioxMCsocy00OCl9ZC5wdXNoKHIpCnJldHVybiBhfSwKUjg6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIg
-dCxzLHIscSxwLG8sbj1iKzEKZm9yKHQ9Yy5sZW5ndGg7bjx0Oysrbil7cz1jLmNoYXJDb2RlQXQobikK
-aWYocz09PTQ2KXtpZihlKWJyZWFrCmU9ITB9ZWxzZXtpZighKCgoKHN8MzIpPj4+MCktOTcmNjU1MzUp
-PDI2fHxzPT09OTV8fHM9PT0zNikpcj1zPj00OCYmczw9NTcKZWxzZSByPSEwCmlmKCFyKWJyZWFrfX1x
-PWMuc3Vic3RyaW5nKGIsbikKaWYoZSl7dD1hLnUKcD1hLmUKaWYocC55PT09MTApcD1wLnoKbz1ILlFv
-KHQscC56KVtxXQppZihvPT1udWxsKUgudmgoJ05vICInK3ErJyIgaW4gIicrSC5tRChwKSsnIicpCmQu
-cHVzaChILmNFKHQscCxvKSl9ZWxzZSBkLnB1c2gocSkKcmV0dXJuIG59LApJMzpmdW5jdGlvbihhLGIp
-e3ZhciB0PWIucG9wKCkKaWYoMD09PXQpe2IucHVzaChILm1aKGEudSwxLCIwJiIpKQpyZXR1cm59aWYo
-MT09PXQpe2IucHVzaChILm1aKGEudSw0LCIxJiIpKQpyZXR1cm59dGhyb3cgSC5iKFAuaFYoIlVuZXhw
-ZWN0ZWQgZXh0ZW5kZWQgb3BlcmF0aW9uICIrSC5kKHQpKSl9LApLUTpmdW5jdGlvbihhLGIsYyl7aWYo
-dHlwZW9mIGM9PSJzdHJpbmciKXJldHVybiBILlEyKGEsYyxhLnNFQSkKZWxzZSBpZih0eXBlb2YgYz09
-Im51bWJlciIpcmV0dXJuIEguVFYoYSxiLGMpCmVsc2UgcmV0dXJuIGN9LApyVDpmdW5jdGlvbihhLGIs
-Yyl7dmFyIHQscz1jLmxlbmd0aApmb3IodD0wO3Q8czsrK3QpY1t0XT1ILktRKGEsYixjW3RdKX0sCldT
-OmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzPWMubGVuZ3RoCmZvcih0PTE7dDxzO3QrPTIpY1t0XT1ILktR
-KGEsYixjW3RdKX0sClRWOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHI9Yi55CmlmKHI9PT0xMCl7aWYo
-Yz09PTApcmV0dXJuIGIuegp0PWIuUQpzPXQubGVuZ3RoCmlmKGM8PXMpcmV0dXJuIHRbYy0xXQpjLT1z
-CmI9Yi56CnI9Yi55fWVsc2UgaWYoYz09PTApcmV0dXJuIGIKaWYociE9PTkpdGhyb3cgSC5iKFAuaFYo
-IkluZGV4ZWQgYmFzZSBtdXN0IGJlIGFuIGludGVyZmFjZSB0eXBlIikpCnQ9Yi5RCmlmKGM8PXQubGVu
-Z3RoKXJldHVybiB0W2MtMV0KdGhyb3cgSC5iKFAuaFYoIkJhZCBpbmRleCAiK2MrIiBmb3IgIitiLloo
-MCkpKX0sCldlOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGsKaWYoYj09
-PWQpcmV0dXJuITAKaWYoSC5BOChkKXx8ZD09PXUuSylyZXR1cm4hMAp0PWIueQppZih0PT09NClyZXR1
-cm4hMAppZihILkE4KGIpKXJldHVybiExCmlmKGI9PT11LlApcmV0dXJuITAKcz10PT09MTMKaWYocylp
-ZihILldlKGEsY1tiLnpdLGMsZCxlKSlyZXR1cm4hMApyPWQueQppZih0PT09NilyZXR1cm4gSC5XZShh
-LGIueixjLGQsZSkKaWYocj09PTYpe3E9ZC56CnJldHVybiBILldlKGEsYixjLHEsZSl9aWYodD09PTgp
-e2lmKCFILldlKGEsYi56LGMsZCxlKSlyZXR1cm4hMQpyZXR1cm4gSC5XZShhLEgueFooYSxiKSxjLGQs
-ZSl9aWYodD09PTcpe3E9SC5XZShhLGIueixjLGQsZSkKcmV0dXJuIHF9aWYocj09PTgpe2lmKEguV2Uo
-YSxiLGMsZC56LGUpKXJldHVybiEwCnJldHVybiBILldlKGEsYixjLEgueFooYSxkKSxlKX1pZihyPT09
-Nyl7cT1ILldlKGEsYixjLGQueixlKQpyZXR1cm4gcX1pZihzKXJldHVybiExCnE9dCE9PTExCmlmKCgh
-cXx8dD09PTEyKSYmZD09PXUuWilyZXR1cm4hMAppZihyPT09MTIpe2lmKGI9PT11LmcpcmV0dXJuITAK
-aWYodCE9PTEyKXJldHVybiExCnA9Yi5RCm89ZC5RCm49cC5sZW5ndGgKaWYobiE9PW8ubGVuZ3RoKXJl
-dHVybiExCmM9Yz09bnVsbD9wOnAuY29uY2F0KGMpCmU9ZT09bnVsbD9vOm8uY29uY2F0KGUpCmZvciht
-PTA7bTxuOysrbSl7bD1wW21dCms9b1ttXQppZighSC5XZShhLGwsYyxrLGUpfHwhSC5XZShhLGssZSxs
-LGMpKXJldHVybiExfXJldHVybiBILmJPKGEsYi56LGMsZC56LGUpfWlmKHI9PT0xMSl7aWYoYj09PXUu
-ZylyZXR1cm4hMAppZihxKXJldHVybiExCnJldHVybiBILmJPKGEsYixjLGQsZSl9aWYodD09PTkpe2lm
-KHIhPT05KXJldHVybiExCnJldHVybiBILnBHKGEsYixjLGQsZSl9cmV0dXJuITF9LApiTzpmdW5jdGlv
-bihhMCxhMSxhMixhMyxhNCl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixpLGgsZyxmLGUsZCxjLGIs
-YQppZighSC5XZShhMCxhMS56LGEyLGEzLnosYTQpKXJldHVybiExCnQ9YTEuUQpzPWEzLlEKcj10LmEK
-cT1zLmEKcD1yLmxlbmd0aApvPXEubGVuZ3RoCmlmKHA+bylyZXR1cm4hMQpuPW8tcAptPXQuYgpsPXMu
-YgprPW0ubGVuZ3RoCmo9bC5sZW5ndGgKaWYocCtrPG8railyZXR1cm4hMQpmb3IoaT0wO2k8cDsrK2kp
-e2g9cltpXQppZighSC5XZShhMCxxW2ldLGE0LGgsYTIpKXJldHVybiExfWZvcihpPTA7aTxuOysraSl7
-aD1tW2ldCmlmKCFILldlKGEwLHFbcCtpXSxhNCxoLGEyKSlyZXR1cm4hMX1mb3IoaT0wO2k8ajsrK2kp
-e2g9bVtuK2ldCmlmKCFILldlKGEwLGxbaV0sYTQsaCxhMikpcmV0dXJuITF9Zz10LmMKZj1zLmMKZT1n
-Lmxlbmd0aApkPWYubGVuZ3RoCmZvcihpPTAsYz0wO2M8ZDtjKz0yKXtiPWZbY10KZG97aWYoaT49ZSly
-ZXR1cm4hMQphPWdbaV0KaSs9Mn13aGlsZShhPGIpCmlmKGI8YSlyZXR1cm4hMQpoPWdbaS0xXQppZigh
-SC5XZShhMCxmW2MrMV0sYTQsaCxhMikpcmV0dXJuITF9cmV0dXJuITB9LApwRzpmdW5jdGlvbihhLGIs
-YyxkLGUpe3ZhciB0LHMscixxLHAsbyxuLG0sbD1iLnosaz1kLnoKaWYobD09PWspe3Q9Yi5RCnM9ZC5R
-CnI9dC5sZW5ndGgKZm9yKHE9MDtxPHI7KytxKXtwPXRbcV0Kbz1zW3FdCmlmKCFILldlKGEscCxjLG8s
-ZSkpcmV0dXJuITF9cmV0dXJuITB9aWYoZD09PXUuSylyZXR1cm4hMApuPUguUW8oYSxsKQppZihuPT1u
-dWxsKXJldHVybiExCm09bltrXQppZihtPT1udWxsKXJldHVybiExCnI9bS5sZW5ndGgKcz1kLlEKZm9y
-KHE9MDtxPHI7KytxKWlmKCFILldlKGEsSC5jRShhLGIsbVtxXSksYyxzW3FdLGUpKXJldHVybiExCnJl
-dHVybiEwfSwKbFI6ZnVuY3Rpb24oYSl7dmFyIHQscz1hLnkKaWYoIShhPT09dS5QKSlpZighSC5BOChh
-KSlpZihzIT09NylpZighKHM9PT02JiZILmxSKGEueikpKXQ9cz09PTgmJkgubFIoYS56KQplbHNlIHQ9
-ITAKZWxzZSB0PSEwCmVsc2UgdD0hMAplbHNlIHQ9ITAKcmV0dXJuIHR9LApjYzpmdW5jdGlvbihhKXty
-ZXR1cm4gSC5BOChhKXx8YT09PXUuS30sCkE4OmZ1bmN0aW9uKGEpe3ZhciB0LHM9YS55CmlmKHMhPT0y
-KWlmKHMhPT0zKWlmKHMhPT00KWlmKHMhPT01KXt0PXUuSwp0PWE9PT10fHxhPT09dH1lbHNlIHQ9ITAK
-ZWxzZSB0PSEwCmVsc2UgdD0hMAplbHNlIHQ9ITAKcmV0dXJuIHR9LApJeDpmdW5jdGlvbihhLGIpe3Zh
-ciB0LHMscj1PYmplY3Qua2V5cyhiKSxxPXIubGVuZ3RoCmZvcih0PTA7dDxxOysrdCl7cz1yW3RdCmFb
-c109YltzXX19LApKYzpmdW5jdGlvbiBKYyhhLGIpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy54PV8u
-cj1fLmM9bnVsbApfLnk9MApfLmN5PV8uY3g9Xy5jaD1fLlE9Xy56PW51bGx9LApFVDpmdW5jdGlvbiBF
-VCgpe3RoaXMuYz10aGlzLmI9dGhpcy5hPW51bGx9LAp1OTpmdW5jdGlvbiB1OSgpe30sCng6ZnVuY3Rp
-b24geChhKXt0aGlzLmE9YX0sClI5OmZ1bmN0aW9uKGEpe3JldHVybiB1LmQuYihhKXx8dS5CLmIoYSl8
-fHUuZHouYihhKXx8dS5JLmIoYSl8fHUuQS5iKGEpfHx1Lmc0LmIoYSl8fHUuZzIuYihhKX0sCkpnOmZ1
-bmN0aW9uKGEpe3JldHVybiB2Lm1hbmdsZWRHbG9iYWxOYW1lc1thXX19LEo9ewpRdTpmdW5jdGlvbihh
-LGIsYyxkKXtyZXR1cm57aTphLHA6YixlOmMseDpkfX0sCmtzOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixx
-LHA9YVt2LmRpc3BhdGNoUHJvcGVydHlOYW1lXQppZihwPT1udWxsKWlmKCQuSz09bnVsbCl7SC5NKCkK
-cD1hW3YuZGlzcGF0Y2hQcm9wZXJ0eU5hbWVdfWlmKHAhPW51bGwpe3Q9cC5wCmlmKCExPT09dClyZXR1
-cm4gcC5pCmlmKCEwPT09dClyZXR1cm4gYQpzPU9iamVjdC5nZXRQcm90b3R5cGVPZihhKQppZih0PT09
-cylyZXR1cm4gcC5pCmlmKHAuZT09PXMpdGhyb3cgSC5iKFAubigiUmV0dXJuIGludGVyY2VwdG9yIGZv
-ciAiK0guZCh0KGEscCkpKSl9cj1hLmNvbnN0cnVjdG9yCnE9cj09bnVsbD9udWxsOnJbJC5BKCldCmlm
-KHEhPW51bGwpcmV0dXJuIHEKcT1ILkcoYSkKaWYocSE9bnVsbClyZXR1cm4gcQppZih0eXBlb2YgYT09
-ImZ1bmN0aW9uIilyZXR1cm4gQy5ERwp0PU9iamVjdC5nZXRQcm90b3R5cGVPZihhKQppZih0PT1udWxs
-KXJldHVybiBDLlpRCmlmKHQ9PT1PYmplY3QucHJvdG90eXBlKXJldHVybiBDLlpRCmlmKHR5cGVvZiBy
-PT0iZnVuY3Rpb24iKXtPYmplY3QuZGVmaW5lUHJvcGVydHkociwkLkEoKSx7dmFsdWU6Qy52QixlbnVt
-ZXJhYmxlOmZhbHNlLHdyaXRhYmxlOnRydWUsY29uZmlndXJhYmxlOnRydWV9KQpyZXR1cm4gQy52Qn1y
-ZXR1cm4gQy52Qn0sClFpOmZ1bmN0aW9uKGEsYil7aWYoYTwwfHxhPjQyOTQ5NjcyOTUpdGhyb3cgSC5i
-KFAuVEUoYSwwLDQyOTQ5NjcyOTUsImxlbmd0aCIsbnVsbCkpCnJldHVybiBKLnB5KG5ldyBBcnJheShh
-KSxiKX0sCktoOmZ1bmN0aW9uKGEsYil7aWYoYTwwKXRocm93IEguYihQLnhZKCJMZW5ndGggbXVzdCBi
-ZSBhIG5vbi1uZWdhdGl2ZSBpbnRlZ2VyOiAiK2EpKQpyZXR1cm4gSC5WTShuZXcgQXJyYXkoYSksYi5D
-KCJqZDwwPiIpKX0sCnB5OmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouRXAoSC5WTShhLGIuQygiamQ8MD4i
-KSksYil9LApFcDpmdW5jdGlvbihhLGIpe2EuZml4ZWQkbGVuZ3RoPUFycmF5CnJldHVybiBhfSwKdW46
-ZnVuY3Rpb24oYSl7YS5maXhlZCRsZW5ndGg9QXJyYXkKYS5pbW11dGFibGUkbGlzdD1BcnJheQpyZXR1
-cm4gYX0sCkdhOmZ1bmN0aW9uKGEpe2lmKGE8MjU2KXN3aXRjaChhKXtjYXNlIDk6Y2FzZSAxMDpjYXNl
-IDExOmNhc2UgMTI6Y2FzZSAxMzpjYXNlIDMyOmNhc2UgMTMzOmNhc2UgMTYwOnJldHVybiEwCmRlZmF1
-bHQ6cmV0dXJuITF9c3dpdGNoKGEpe2Nhc2UgNTc2MDpjYXNlIDgxOTI6Y2FzZSA4MTkzOmNhc2UgODE5
-NDpjYXNlIDgxOTU6Y2FzZSA4MTk2OmNhc2UgODE5NzpjYXNlIDgxOTg6Y2FzZSA4MTk5OmNhc2UgODIw
-MDpjYXNlIDgyMDE6Y2FzZSA4MjAyOmNhc2UgODIzMjpjYXNlIDgyMzM6Y2FzZSA4MjM5OmNhc2UgODI4
-NzpjYXNlIDEyMjg4OmNhc2UgNjUyNzk6cmV0dXJuITAKZGVmYXVsdDpyZXR1cm4hMX19LAptbTpmdW5j
-dGlvbihhLGIpe3ZhciB0LHMKZm9yKHQ9YS5sZW5ndGg7Yjx0Oyl7cz1DLnhCLlcoYSxiKQppZihzIT09
-MzImJnMhPT0xMyYmIUouR2EocykpYnJlYWs7KytifXJldHVybiBifSwKYzE6ZnVuY3Rpb24oYSxiKXt2
-YXIgdCxzCmZvcig7Yj4wO2I9dCl7dD1iLTEKcz1DLnhCLm0oYSx0KQppZihzIT09MzImJnMhPT0xMyYm
-IUouR2EocykpYnJlYWt9cmV0dXJuIGJ9LApSRTpmdW5jdGlvbihhKXtpZihhPT1udWxsKXJldHVybiBh
-CmlmKHR5cGVvZiBhIT0ib2JqZWN0Iil7aWYodHlwZW9mIGE9PSJmdW5jdGlvbiIpcmV0dXJuIEouYzUu
-cHJvdG90eXBlCnJldHVybiBhfWlmKGEgaW5zdGFuY2VvZiBQLk1oKXJldHVybiBhCnJldHVybiBKLmtz
-KGEpfSwKVEo6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJudW1iZXIiKXJldHVybiBKLnFJLnByb3Rv
-dHlwZQppZih0eXBlb2YgYT09InN0cmluZyIpcmV0dXJuIEouRHIucHJvdG90eXBlCmlmKGE9PW51bGwp
-cmV0dXJuIGEKaWYoYS5jb25zdHJ1Y3Rvcj09QXJyYXkpcmV0dXJuIEouamQucHJvdG90eXBlCmlmKHR5
-cGVvZiBhIT0ib2JqZWN0Iil7aWYodHlwZW9mIGE9PSJmdW5jdGlvbiIpcmV0dXJuIEouYzUucHJvdG90
-eXBlCnJldHVybiBhfWlmKGEgaW5zdGFuY2VvZiBQLk1oKXJldHVybiBhCnJldHVybiBKLmtzKGEpfSwK
-VTY6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJzdHJpbmciKXJldHVybiBKLkRyLnByb3RvdHlwZQpp
-ZihhPT1udWxsKXJldHVybiBhCmlmKGEuY29uc3RydWN0b3I9PUFycmF5KXJldHVybiBKLmpkLnByb3Rv
-dHlwZQppZih0eXBlb2YgYSE9Im9iamVjdCIpe2lmKHR5cGVvZiBhPT0iZnVuY3Rpb24iKXJldHVybiBK
-LmM1LnByb3RvdHlwZQpyZXR1cm4gYX1pZihhIGluc3RhbmNlb2YgUC5NaClyZXR1cm4gYQpyZXR1cm4g
-Si5rcyhhKX0sCmlhOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIil7aWYoTWF0aC5mbG9v
-cihhKT09YSlyZXR1cm4gSi51ci5wcm90b3R5cGUKcmV0dXJuIEouVkEucHJvdG90eXBlfWlmKHR5cGVv
-ZiBhPT0ic3RyaW5nIilyZXR1cm4gSi5Eci5wcm90b3R5cGUKaWYoYT09bnVsbClyZXR1cm4gSi5ZRS5w
-cm90b3R5cGUKaWYodHlwZW9mIGE9PSJib29sZWFuIilyZXR1cm4gSi55RS5wcm90b3R5cGUKaWYoYS5j
-b25zdHJ1Y3Rvcj09QXJyYXkpcmV0dXJuIEouamQucHJvdG90eXBlCmlmKHR5cGVvZiBhIT0ib2JqZWN0
-Iil7aWYodHlwZW9mIGE9PSJmdW5jdGlvbiIpcmV0dXJuIEouYzUucHJvdG90eXBlCnJldHVybiBhfWlm
-KGEgaW5zdGFuY2VvZiBQLk1oKXJldHVybiBhCnJldHVybiBKLmtzKGEpfSwKclk6ZnVuY3Rpb24oYSl7
-aWYodHlwZW9mIGE9PSJzdHJpbmciKXJldHVybiBKLkRyLnByb3RvdHlwZQppZihhPT1udWxsKXJldHVy
-biBhCmlmKCEoYSBpbnN0YW5jZW9mIFAuTWgpKXJldHVybiBKLmtkLnByb3RvdHlwZQpyZXR1cm4gYX0s
-CncxOmZ1bmN0aW9uKGEpe2lmKGE9PW51bGwpcmV0dXJuIGEKaWYoYS5jb25zdHJ1Y3Rvcj09QXJyYXkp
-cmV0dXJuIEouamQucHJvdG90eXBlCmlmKHR5cGVvZiBhIT0ib2JqZWN0Iil7aWYodHlwZW9mIGE9PSJm
-dW5jdGlvbiIpcmV0dXJuIEouYzUucHJvdG90eXBlCnJldHVybiBhfWlmKGEgaW5zdGFuY2VvZiBQLk1o
-KXJldHVybiBhCnJldHVybiBKLmtzKGEpfSwKQWM6ZnVuY3Rpb24oYSl7cmV0dXJuIEouaWEoYSkuWihh
-KX0sCkNNOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybiBKLlJFKGEpLmR1KGEsYixjLGQpfSwKRkw6ZnVu
-Y3Rpb24oYSxiKXtyZXR1cm4gSi5yWShhKS5kZChhLGIpfSwKR0E6ZnVuY3Rpb24oYSxiKXtyZXR1cm4g
-Si53MShhKS5FKGEsYil9LApHcjpmdW5jdGlvbihhKXtyZXR1cm4gSi5SRShhKS5nbVcoYSl9LApIOmZ1
-bmN0aW9uKGEpe3JldHVybiBKLlU2KGEpLmdBKGEpfSwKSVQ6ZnVuY3Rpb24oYSl7cmV0dXJuIEoudzEo
-YSkuZ2t6KGEpfSwKSnk6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi5pYShhKS5lNyhhLGIpfSwKS1Y6ZnVu
-Y3Rpb24oYSxiKXtyZXR1cm4gSi5yWShhKS5HKGEsYil9LApMdDpmdW5jdGlvbihhKXtyZXR1cm4gSi5S
-RShhKS53ZyhhKX0sCk0xOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gSi53MShhKS5FMihhLGIsYyl9LApR
-ejpmdW5jdGlvbihhLGIpe3JldHVybiBKLnJZKGEpLlcoYSxiKX0sClJNOmZ1bmN0aW9uKGEsYil7aWYo
-YT09bnVsbClyZXR1cm4gYj09bnVsbAppZih0eXBlb2YgYSE9Im9iamVjdCIpcmV0dXJuIGIhPW51bGwm
-JmE9PT1iCnJldHVybiBKLmlhKGEpLkROKGEsYil9LApUMDpmdW5jdGlvbihhKXtyZXR1cm4gSi5yWShh
-KS5iUyhhKX0sCmE2OmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouclkoYSkubShhLGIpfSwKYlQ6ZnVuY3Rp
-b24oYSl7cmV0dXJuIEouUkUoYSkuRDQoYSl9LApjSDpmdW5jdGlvbihhKXtyZXR1cm4gSi5yWShhKS5o
-YyhhKX0sCmRSOmZ1bmN0aW9uKGEpe3JldHVybiBKLlJFKGEpLmdQKGEpfSwKZFo6ZnVuY3Rpb24oYSxi
-LGMsZCl7cmV0dXJuIEouUkUoYSkuT24oYSxiLGMsZCl9LApkZzpmdW5jdGlvbihhLGIsYyxkKXtyZXR1
-cm4gSi5yWShhKS5pNyhhLGIsYyxkKX0sCmRoOmZ1bmN0aW9uKGEpe3JldHVybiBKLlJFKGEpLkZGKGEp
-fSwKaGY6ZnVuY3Rpb24oYSl7cmV0dXJuIEouaWEoYSkuZ2lPKGEpfSwKaWc6ZnVuY3Rpb24oYSl7cmV0
-dXJuIEouUkUoYSkuZ1FnKGEpfSwKbDU6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi5SRShhKS5zaGYoYSxi
-KX0sCmxkOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gSi5yWShhKS5OaihhLGIsYyl9LAptOmZ1bmN0aW9u
-KGEsYil7aWYodHlwZW9mIGE9PSJudW1iZXIiJiZ0eXBlb2YgYj09Im51bWJlciIpcmV0dXJuIGErYgpy
-ZXR1cm4gSi5USihhKS5oKGEsYil9LApwNDpmdW5jdGlvbihhLGIpe3JldHVybiBKLnJZKGEpLlRjKGEs
-Yil9LApxMDpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIEouclkoYSkuUWkoYSxiLGMpfSwKcUY6ZnVuY3Rp
-b24oYSl7cmV0dXJuIEouUkUoYSkuZ1ZsKGEpfSwKdEg6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBKLlJF
-KGEpLnBrKGEsYixjKX0sCng5OmZ1bmN0aW9uKGEsYil7aWYodHlwZW9mIGI9PT0ibnVtYmVyIilpZihh
-LmNvbnN0cnVjdG9yPT1BcnJheXx8dHlwZW9mIGE9PSJzdHJpbmcifHxILndWKGEsYVt2LmRpc3BhdGNo
-UHJvcGVydHlOYW1lXSkpaWYoYj4+PjA9PT1iJiZiPGEubGVuZ3RoKXJldHVybiBhW2JdCnJldHVybiBK
-LlU2KGEpLnEoYSxiKX0sCnpsOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouVTYoYSkudGcoYSxiKX0sCnZC
-OmZ1bmN0aW9uIHZCKCl7fSwKeUU6ZnVuY3Rpb24geUUoKXt9LApZRTpmdW5jdGlvbiBZRSgpe30sCk1G
-OmZ1bmN0aW9uIE1GKCl7fSwKaUM6ZnVuY3Rpb24gaUMoKXt9LAprZDpmdW5jdGlvbiBrZCgpe30sCmM1
-OmZ1bmN0aW9uIGM1KCl7fSwKamQ6ZnVuY3Rpb24gamQoYSl7dGhpcy4kdGk9YX0sClBvOmZ1bmN0aW9u
-IFBvKGEpe3RoaXMuJHRpPWF9LAptMTpmdW5jdGlvbiBtMShhLGIsYyl7dmFyIF89dGhpcwpfLmE9YQpf
-LmI9YgpfLmM9MApfLmQ9bnVsbApfLiR0aT1jfSwKcUk6ZnVuY3Rpb24gcUkoKXt9LAp1cjpmdW5jdGlv
-biB1cigpe30sClZBOmZ1bmN0aW9uIFZBKCl7fSwKRHI6ZnVuY3Rpb24gRHIoKXt9fSxQPXsKT2o6ZnVu
-Y3Rpb24oKXt2YXIgdCxzLHI9e30KaWYoc2VsZi5zY2hlZHVsZUltbWVkaWF0ZSE9bnVsbClyZXR1cm4g
-UC5FWCgpCmlmKHNlbGYuTXV0YXRpb25PYnNlcnZlciE9bnVsbCYmc2VsZi5kb2N1bWVudCE9bnVsbCl7
-dD1zZWxmLmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImRpdiIpCnM9c2VsZi5kb2N1bWVudC5jcmVhdGVF
-bGVtZW50KCJzcGFuIikKci5hPW51bGwKbmV3IHNlbGYuTXV0YXRpb25PYnNlcnZlcihILnRSKG5ldyBQ
-LnRoKHIpLDEpKS5vYnNlcnZlKHQse2NoaWxkTGlzdDp0cnVlfSkKcmV0dXJuIG5ldyBQLmhhKHIsdCxz
-KX1lbHNlIGlmKHNlbGYuc2V0SW1tZWRpYXRlIT1udWxsKXJldHVybiBQLnl0KCkKcmV0dXJuIFAucVco
-KX0sClpWOmZ1bmN0aW9uKGEpe3NlbGYuc2NoZWR1bGVJbW1lZGlhdGUoSC50UihuZXcgUC5Wcyh1Lk0u
-YShhKSksMCkpfSwKb0E6ZnVuY3Rpb24oYSl7c2VsZi5zZXRJbW1lZGlhdGUoSC50UihuZXcgUC5GdCh1
-Lk0uYShhKSksMCkpfSwKQno6ZnVuY3Rpb24oYSl7dS5NLmEoYSkKUC5RTigwLGEpfSwKUU46ZnVuY3Rp
-b24oYSxiKXt2YXIgdD1uZXcgUC5XMygpCnQuQ1koYSxiKQpyZXR1cm4gdH0sCkZYOmZ1bmN0aW9uKGEp
-e3JldHVybiBuZXcgUC5paChuZXcgUC52cygkLlgzLGEuQygidnM8MD4iKSksYS5DKCJpaDwwPiIpKX0s
-CkRJOmZ1bmN0aW9uKGEsYil7YS4kMigwLG51bGwpCmIuYj0hMApyZXR1cm4gYi5hfSwKalE6ZnVuY3Rp
-b24oYSxiKXtQLkplKGEsYil9LAp5QzpmdW5jdGlvbihhLGIpe2IuYU0oMCxhKX0sCmYzOmZ1bmN0aW9u
-KGEsYil7Yi53MChILlJ1KGEpLEgudHMoYSkpfSwKSmU6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9bmV3
-IFAuV00oYikscT1uZXcgUC5TWChiKQppZihhIGluc3RhbmNlb2YgUC52cylhLlFkKHIscSx1LnopCmVs
-c2V7dD11LnoKaWYodS5jLmIoYSkpYS5TcShyLHEsdCkKZWxzZXtzPW5ldyBQLnZzKCQuWDMsdS5fKQpz
-LmE9NApzLmM9YQpzLlFkKHIscSx0KX19fSwKbHo6ZnVuY3Rpb24oYSl7dmFyIHQ9ZnVuY3Rpb24oYixj
-KXtyZXR1cm4gZnVuY3Rpb24oZCxlKXt3aGlsZSh0cnVlKXRyeXtiKGQsZSkKYnJlYWt9Y2F0Y2gocyl7
-ZT1zCmQ9Y319fShhLDEpCnJldHVybiAkLlgzLkxqKG5ldyBQLkdzKHQpLHUuUCx1LnEsdS56KX0sCkdR
-OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5GeShhLDEpfSwKVGg6ZnVuY3Rpb24oKXtyZXR1cm4gQy53
-UX0sClltOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5GeShhLDMpfSwKbDA6ZnVuY3Rpb24oYSxiKXty
-ZXR1cm4gbmV3IFAucTQoYSxiLkMoInE0PDA+IikpfSwKazM6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIK
-Yi5hPTEKdHJ5e2EuU3EobmV3IFAucFYoYiksbmV3IFAuVTcoYiksdS5QKX1jYXRjaChyKXt0PUguUnUo
-cikKcz1ILnRzKHIpClAucmIobmV3IFAudnIoYix0LHMpKX19LApBOTpmdW5jdGlvbihhLGIpe3ZhciB0
-LHMscgpmb3IodD11Ll87cz1hLmEscz09PTI7KWE9dC5hKGEuYykKaWYocz49NCl7cj1iLmFoKCkKYi5h
-PWEuYQpiLmM9YS5jClAuSFooYixyKX1lbHNle3I9dS54LmEoYi5jKQpiLmE9MgpiLmM9YQphLmpRKHIp
-fX0sCkhaOmZ1bmN0aW9uKGEsYTApe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZixlLGQ9
-bnVsbCxjPXt9LGI9Yy5hPWEKZm9yKHQ9dS5uLHM9dS54LHI9dS5jOyEwOyl7cT17fQpwPWIuYT09PTgK
-aWYoYTA9PW51bGwpe2lmKHApe289dC5hKGIuYykKUC5MMihkLGQsYi5iLG8uYSxvLmIpfXJldHVybn1x
-LmE9YTAKbj1hMC5hCmZvcihiPWEwO24hPW51bGw7Yj1uLG49bSl7Yi5hPW51bGwKUC5IWihjLmEsYikK
-cS5hPW4KbT1uLmF9bD1jLmEKaz1sLmMKcS5iPXAKcS5jPWsKaj0hcAppZihqKXtpPWIuYwppPShpJjEp
-IT09MHx8KGkmMTUpPT09OH1lbHNlIGk9ITAKaWYoaSl7aD1iLmIuYgppZihwKXtpPWwuYj09PWgKaT0h
-KGl8fGkpfWVsc2UgaT0hMQppZihpKXt0LmEoaykKUC5MMihkLGQsbC5iLGsuYSxrLmIpCnJldHVybn1n
-PSQuWDMKaWYoZyE9PWgpJC5YMz1oCmVsc2UgZz1kCmI9Yi5jCmlmKChiJjE1KT09PTgpbmV3IFAuUlQo
-cSxjLHApLiQwKCkKZWxzZSBpZihqKXtpZigoYiYxKSE9PTApbmV3IFAucnEocSxrKS4kMCgpfWVsc2Ug
-aWYoKGImMikhPT0wKW5ldyBQLlJXKGMscSkuJDAoKQppZihnIT1udWxsKSQuWDM9ZwpiPXEuYwppZihy
-LmIoYikpe2Y9cS5hLmIKaWYoYi5hPj00KXtlPXMuYShmLmMpCmYuYz1udWxsCmEwPWYuTjgoZSkKZi5h
-PWIuYQpmLmM9Yi5jCmMuYT1iCmNvbnRpbnVlfWVsc2UgUC5BOShiLGYpCnJldHVybn19Zj1xLmEuYgpl
-PXMuYShmLmMpCmYuYz1udWxsCmEwPWYuTjgoZSkKYj1xLmIKbD1xLmMKaWYoIWIpe2YuJHRpLmMuYShs
-KQpmLmE9NApmLmM9bH1lbHNle3QuYShsKQpmLmE9OApmLmM9bH1jLmE9ZgpiPWZ9fSwKVkg6ZnVuY3Rp
-b24oYSxiKXt2YXIgdAppZih1LmFnLmIoYSkpcmV0dXJuIGIuTGooYSx1LnosdS5LLHUubCkKdD11LmJJ
-CmlmKHQuYihhKSlyZXR1cm4gdC5hKGEpCnRocm93IEguYihQLkwzKGEsIm9uRXJyb3IiLCJFcnJvciBo
-YW5kbGVyIG11c3QgYWNjZXB0IG9uZSBPYmplY3Qgb3Igb25lIE9iamVjdCBhbmQgYSBTdGFja1RyYWNl
-IGFzIGFyZ3VtZW50cywgYW5kIHJldHVybiBhIGEgdmFsaWQgcmVzdWx0IikpfSwKcHU6ZnVuY3Rpb24o
-KXt2YXIgdCxzCmZvcih0PSQuUzY7dCE9bnVsbDt0PSQuUzYpeyQubWc9bnVsbApzPXQuYgokLlM2PXMK
-aWYocz09bnVsbCkkLms4PW51bGwKdC5hLiQwKCl9fSwKZU46ZnVuY3Rpb24oKXskLlVEPSEwCnRyeXtQ
-LnB1KCl9ZmluYWxseXskLm1nPW51bGwKJC5VRD0hMQppZigkLlM2IT1udWxsKSQudXQoKS4kMShQLlY5
-KCkpfX0sCmVXOmZ1bmN0aW9uKGEpe3ZhciB0PW5ldyBQLk9NKGEpLHM9JC5rOAppZihzPT1udWxsKXsk
-LlM2PSQuazg9dAppZighJC5VRCkkLnV0KCkuJDEoUC5WOSgpKX1lbHNlICQuazg9cy5iPXR9LApyUjpm
-dW5jdGlvbihhKXt2YXIgdCxzLHIscT0kLlM2CmlmKHE9PW51bGwpe1AuZVcoYSkKJC5tZz0kLms4CnJl
-dHVybn10PW5ldyBQLk9NKGEpCnM9JC5tZwppZihzPT1udWxsKXt0LmI9cQokLlM2PSQubWc9dH1lbHNl
-e3I9cy5iCnQuYj1yCiQubWc9cy5iPXQKaWYocj09bnVsbCkkLms4PXR9fSwKcmI6ZnVuY3Rpb24oYSl7
-dmFyIHQ9bnVsbCxzPSQuWDMKaWYoQy5OVT09PXMpe1AuVGsodCx0LEMuTlUsYSkKcmV0dXJufVAuVGso
-dCx0LHMsdS5NLmEocy5HWShhKSkpfSwKUXc6ZnVuY3Rpb24oYSxiKXtQLlVJKGEsInN0cmVhbSIsYi5D
-KCJxaDwwPiIpKQpyZXR1cm4gbmV3IFAueEkoYi5DKCJ4STwwPiIpKX0sClRsOmZ1bmN0aW9uKGEsYil7
-dmFyIHQ9Yj09bnVsbD9QLnYwKGEpOmIKUC5VSShhLCJlcnJvciIsdS5LKQpyZXR1cm4gbmV3IFAuT0go
-YSx0KX0sCnYwOmZ1bmN0aW9uKGEpe3ZhciB0CmlmKHUuVy5iKGEpKXt0PWEuZ0lJKCkKaWYodCE9bnVs
-bClyZXR1cm4gdH1yZXR1cm4gQy5wZH0sCkwyOmZ1bmN0aW9uKGEsYixjLGQsZSl7UC5yUihuZXcgUC5w
-SyhkLGUpKX0sClQ4OmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHQscz0kLlgzCmlmKHM9PT1jKXJldHVy
-biBkLiQwKCkKJC5YMz1jCnQ9cwp0cnl7cz1kLiQwKCkKcmV0dXJuIHN9ZmluYWxseXskLlgzPXR9fSwK
-eXY6ZnVuY3Rpb24oYSxiLGMsZCxlLGYsZyl7dmFyIHQscz0kLlgzCmlmKHM9PT1jKXJldHVybiBkLiQx
-KGUpCiQuWDM9Ywp0PXMKdHJ5e3M9ZC4kMShlKQpyZXR1cm4gc31maW5hbGx5eyQuWDM9dH19LApReDpm
-dW5jdGlvbihhLGIsYyxkLGUsZixnLGgsaSl7dmFyIHQscz0kLlgzCmlmKHM9PT1jKXJldHVybiBkLiQy
-KGUsZikKJC5YMz1jCnQ9cwp0cnl7cz1kLiQyKGUsZikKcmV0dXJuIHN9ZmluYWxseXskLlgzPXR9fSwK
-VGs6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQKdS5NLmEoZCkKdD1DLk5VIT09YwppZih0KWQ9ISghdHx8
-ITEpP2MuR1koZCk6Yy5SVChkLHUuSCkKUC5lVyhkKX0sCnRoOmZ1bmN0aW9uIHRoKGEpe3RoaXMuYT1h
-fSwKaGE6ZnVuY3Rpb24gaGEoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKVnM6ZnVu
-Y3Rpb24gVnMoYSl7dGhpcy5hPWF9LApGdDpmdW5jdGlvbiBGdChhKXt0aGlzLmE9YX0sClczOmZ1bmN0
-aW9uIFczKCl7fSwKeUg6ZnVuY3Rpb24geUgoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCmloOmZ1bmN0
-aW9uIGloKGEsYil7dGhpcy5hPWEKdGhpcy5iPSExCnRoaXMuJHRpPWJ9LApXTTpmdW5jdGlvbiBXTShh
-KXt0aGlzLmE9YX0sClNYOmZ1bmN0aW9uIFNYKGEpe3RoaXMuYT1hfSwKR3M6ZnVuY3Rpb24gR3MoYSl7
-dGhpcy5hPWF9LApGeTpmdW5jdGlvbiBGeShhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKR1Y6ZnVuY3Rp
-b24gR1YoYSxiKXt2YXIgXz10aGlzCl8uYT1hCl8uZD1fLmM9Xy5iPW51bGwKXy4kdGk9Yn0sCnE0OmZ1
-bmN0aW9uIHE0KGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9Yn0sCmI4OmZ1bmN0aW9uIGI4KCl7fSwKUGY6
-ZnVuY3Rpb24gUGYoKXt9LApaZjpmdW5jdGlvbiBaZihhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApG
-ZTpmdW5jdGlvbiBGZShhLGIsYyxkLGUpe3ZhciBfPXRoaXMKXy5hPW51bGwKXy5iPWEKXy5jPWIKXy5k
-PWMKXy5lPWQKXy4kdGk9ZX0sCnZzOmZ1bmN0aW9uIHZzKGEsYil7dmFyIF89dGhpcwpfLmE9MApfLmI9
-YQpfLmM9bnVsbApfLiR0aT1ifSwKZGE6ZnVuY3Rpb24gZGEoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0s
-Cm9ROmZ1bmN0aW9uIG9RKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApwVjpmdW5jdGlvbiBwVihhKXt0
-aGlzLmE9YX0sClU3OmZ1bmN0aW9uIFU3KGEpe3RoaXMuYT1hfSwKdnI6ZnVuY3Rpb24gdnIoYSxiLGMp
-e3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKckg6ZnVuY3Rpb24gckgoYSxiKXt0aGlzLmE9YQp0
-aGlzLmI9Yn0sCktGOmZ1bmN0aW9uIEtGKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApaTDpmdW5jdGlv
-biBaTChhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApSVDpmdW5jdGlvbiBSVChhLGIs
-Yyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApqWjpmdW5jdGlvbiBqWihhKXt0aGlzLmE9YX0s
-CnJxOmZ1bmN0aW9uIHJxKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApSVzpmdW5jdGlvbiBSVyhhLGIp
-e3RoaXMuYT1hCnRoaXMuYj1ifSwKT006ZnVuY3Rpb24gT00oYSl7dGhpcy5hPWEKdGhpcy5iPW51bGx9
-LApxaDpmdW5jdGlvbiBxaCgpe30sCkI1OmZ1bmN0aW9uIEI1KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9
-LAp1TzpmdW5jdGlvbiB1TyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKTU86ZnVuY3Rpb24gTU8oKXt9
-LAprVDpmdW5jdGlvbiBrVCgpe30sCnhJOmZ1bmN0aW9uIHhJKGEpe3RoaXMuJHRpPWF9LApPSDpmdW5j
-dGlvbiBPSChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKbTA6ZnVuY3Rpb24gbTAoKXt9LApwSzpmdW5j
-dGlvbiBwSyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKSmk6ZnVuY3Rpb24gSmkoKXt9LApoajpmdW5j
-dGlvbiBoaihhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApWcDpmdW5jdGlvbiBWcChh
-LGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKT1I6ZnVuY3Rpb24gT1IoYSxiLGMpe3RoaXMuYT1hCnRoaXMu
-Yj1iCnRoaXMuYz1jfSwKRUY6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBiLkMoIkA8MD4iKS5LcShjKS5D
-KCJGbzwxLDI+IikuYShILkI3KGEsbmV3IEguTjUoYi5DKCJAPDA+IikuS3EoYykuQygiTjU8MSwyPiIp
-KSkpfSwKRmw6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IEguTjUoYS5DKCJAPDA+IikuS3EoYikuQygi
-TjU8MSwyPiIpKX0sCkxzOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5iNihhLkMoImI2PDA+IikpfSwK
-VDI6ZnVuY3Rpb24oKXt2YXIgdD1PYmplY3QuY3JlYXRlKG51bGwpCnRbIjxub24taWRlbnRpZmllci1r
-ZXk+Il09dApkZWxldGUgdFsiPG5vbi1pZGVudGlmaWVyLWtleT4iXQpyZXR1cm4gdH0sCnJqOmZ1bmN0
-aW9uKGEsYixjKXt2YXIgdD1uZXcgUC5sbShhLGIsYy5DKCJsbTwwPiIpKQp0LmM9YS5lCnJldHVybiB0
-fSwKRVA6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMKaWYoUC5oQihhKSl7aWYoYj09PSIoIiYmYz09PSIp
-IilyZXR1cm4iKC4uLikiCnJldHVybiBiKyIuLi4iK2N9dD1ILlZNKFtdLHUucykKQy5ObS5pKCQueGcs
-YSkKdHJ5e1AuVnIoYSx0KX1maW5hbGx5e2lmKDA+PSQueGcubGVuZ3RoKXJldHVybiBILmsoJC54Zywt
-MSkKJC54Zy5wb3AoKX1zPVAudmcoYix1LlIuYSh0KSwiLCAiKStjCnJldHVybiBzLmNoYXJDb2RlQXQo
-MCk9PTA/czpzfSwKV0U6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMKaWYoUC5oQihhKSlyZXR1cm4gYisi
-Li4uIitjCnQ9bmV3IFAuUm4oYikKQy5ObS5pKCQueGcsYSkKdHJ5e3M9dApzLmE9UC52ZyhzLmEsYSwi
-LCAiKX1maW5hbGx5e2lmKDA+PSQueGcubGVuZ3RoKXJldHVybiBILmsoJC54ZywtMSkKJC54Zy5wb3Ao
-KX10LmErPWMKcz10LmEKcmV0dXJuIHMuY2hhckNvZGVBdCgwKT09MD9zOnN9LApoQjpmdW5jdGlvbihh
-KXt2YXIgdCxzCmZvcih0PSQueGcubGVuZ3RoLHM9MDtzPHQ7KytzKWlmKGE9PT0kLnhnW3NdKXJldHVy
-biEwCnJldHVybiExfSwKVnI6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG8sbixtPWEuZ2t6KGEp
-LGw9MCxrPTAKd2hpbGUoITApe2lmKCEobDw4MHx8azwzKSlicmVhawppZighbS5GKCkpcmV0dXJuCnQ9
-SC5kKG0uZ2woKSkKQy5ObS5pKGIsdCkKbCs9dC5sZW5ndGgrMjsrK2t9aWYoIW0uRigpKXtpZihrPD01
-KXJldHVybgppZigwPj1iLmxlbmd0aClyZXR1cm4gSC5rKGIsLTEpCnM9Yi5wb3AoKQppZigwPj1iLmxl
-bmd0aClyZXR1cm4gSC5rKGIsLTEpCnI9Yi5wb3AoKX1lbHNle3E9bS5nbCgpOysrawppZighbS5GKCkp
-e2lmKGs8PTQpe0MuTm0uaShiLEguZChxKSkKcmV0dXJufXM9SC5kKHEpCmlmKDA+PWIubGVuZ3RoKXJl
-dHVybiBILmsoYiwtMSkKcj1iLnBvcCgpCmwrPXMubGVuZ3RoKzJ9ZWxzZXtwPW0uZ2woKTsrK2sKZm9y
-KDttLkYoKTtxPXAscD1vKXtvPW0uZ2woKTsrK2sKaWYoaz4xMDApe3doaWxlKCEwKXtpZighKGw+NzUm
-Jms+MykpYnJlYWsKaWYoMD49Yi5sZW5ndGgpcmV0dXJuIEguayhiLC0xKQpsLT1iLnBvcCgpLmxlbmd0
-aCsyOy0ta31DLk5tLmkoYiwiLi4uIikKcmV0dXJufX1yPUguZChxKQpzPUguZChwKQpsKz1zLmxlbmd0
-aCtyLmxlbmd0aCs0fX1pZihrPmIubGVuZ3RoKzIpe2wrPTUKbj0iLi4uIn1lbHNlIG49bnVsbAp3aGls
-ZSghMCl7aWYoIShsPjgwJiZiLmxlbmd0aD4zKSlicmVhawppZigwPj1iLmxlbmd0aClyZXR1cm4gSC5r
-KGIsLTEpCmwtPWIucG9wKCkubGVuZ3RoKzIKaWYobj09bnVsbCl7bCs9NQpuPSIuLi4ifX1pZihuIT1u
-dWxsKUMuTm0uaShiLG4pCkMuTm0uaShiLHIpCkMuTm0uaShiLHMpfSwKdE06ZnVuY3Rpb24oYSxiKXt2
-YXIgdCxzLHI9UC5McyhiKQpmb3IodD1hLmxlbmd0aCxzPTA7czxhLmxlbmd0aDthLmxlbmd0aD09PXR8
-fCgwLEgubGspKGEpLCsrcylyLmkoMCxiLmEoYVtzXSkpCnJldHVybiByfSwKbk86ZnVuY3Rpb24oYSl7
-dmFyIHQscz17fQppZihQLmhCKGEpKXJldHVybiJ7Li4ufSIKdD1uZXcgUC5SbigiIikKdHJ5e0MuTm0u
-aSgkLnhnLGEpCnQuYSs9InsiCnMuYT0hMAphLksoMCxuZXcgUC5yYShzLHQpKQp0LmErPSJ9In1maW5h
-bGx5e2lmKDA+PSQueGcubGVuZ3RoKXJldHVybiBILmsoJC54ZywtMSkKJC54Zy5wb3AoKX1zPXQuYQpy
-ZXR1cm4gcy5jaGFyQ29kZUF0KDApPT0wP3M6c30sCmI2OmZ1bmN0aW9uIGI2KGEpe3ZhciBfPXRoaXMK
-Xy5hPTAKXy5mPV8uZT1fLmQ9Xy5jPV8uYj1udWxsCl8ucj0wCl8uJHRpPWF9LApibjpmdW5jdGlvbiBi
-bihhKXt0aGlzLmE9YQp0aGlzLmM9dGhpcy5iPW51bGx9LApsbTpmdW5jdGlvbiBsbShhLGIsYyl7dmFy
-IF89dGhpcwpfLmE9YQpfLmI9YgpfLmQ9Xy5jPW51bGwKXy4kdGk9Y30sCm1XOmZ1bmN0aW9uIG1XKCl7
-fSwKTFU6ZnVuY3Rpb24gTFUoKXt9LApsRDpmdW5jdGlvbiBsRCgpe30sCmlsOmZ1bmN0aW9uIGlsKCl7
-fSwKcmE6ZnVuY3Rpb24gcmEoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCllrOmZ1bmN0aW9uIFlrKCl7
-fSwKeVE6ZnVuY3Rpb24geVEoYSl7dGhpcy5hPWF9LApLUDpmdW5jdGlvbiBLUCgpe30sClBuOmZ1bmN0
-aW9uIFBuKCl7fSwKR2o6ZnVuY3Rpb24gR2ooYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKTWE6ZnVu
-Y3Rpb24gTWEoKXt9LApWajpmdW5jdGlvbiBWaigpe30sClh2OmZ1bmN0aW9uIFh2KCl7fSwKblk6ZnVu
-Y3Rpb24gblkoKXt9LApUQzpmdW5jdGlvbiBUQygpe30sClJVOmZ1bmN0aW9uIFJVKCl7fSwKQlM6ZnVu
-Y3Rpb24oYSxiKXt2YXIgdCxzLHIscQppZih0eXBlb2YgYSE9InN0cmluZyIpdGhyb3cgSC5iKEguSShh
-KSkKdD1udWxsCnRyeXt0PUpTT04ucGFyc2UoYSl9Y2F0Y2gocil7cz1ILlJ1KHIpCnE9UC5ycihTdHJp
-bmcocyksbnVsbCxudWxsKQp0aHJvdyBILmIocSl9cT1QLlFlKHQpCnJldHVybiBxfSwKUWU6ZnVuY3Rp
-b24oYSl7dmFyIHQKaWYoYT09bnVsbClyZXR1cm4gbnVsbAppZih0eXBlb2YgYSE9Im9iamVjdCIpcmV0
-dXJuIGEKaWYoT2JqZWN0LmdldFByb3RvdHlwZU9mKGEpIT09QXJyYXkucHJvdG90eXBlKXJldHVybiBu
-ZXcgUC51dyhhLE9iamVjdC5jcmVhdGUobnVsbCkpCmZvcih0PTA7dDxhLmxlbmd0aDsrK3QpYVt0XT1Q
-LlFlKGFbdF0pCnJldHVybiBhfSwKa3k6ZnVuY3Rpb24oYSxiLGMsZCl7aWYoYiBpbnN0YW5jZW9mIFVp
-bnQ4QXJyYXkpcmV0dXJuIFAuUlAoITEsYixjLGQpCnJldHVybiBudWxsfSwKUlA6ZnVuY3Rpb24oYSxi
-LGMsZCl7dmFyIHQscyxyPSQudEwoKQppZihyPT1udWxsKXJldHVybiBudWxsCnQ9MD09PWMKaWYodCYm
-ITApcmV0dXJuIFAuT1EocixiKQpzPWIubGVuZ3RoCmQ9UC5qQihjLGQscykKaWYodCYmZD09PXMpcmV0
-dXJuIFAuT1EocixiKQpyZXR1cm4gUC5PUShyLGIuc3ViYXJyYXkoYyxkKSl9LApPUTpmdW5jdGlvbihh
-LGIpe2lmKFAuQWooYikpcmV0dXJuIG51bGwKcmV0dXJuIFAuSmgoYSxiKX0sCkpoOmZ1bmN0aW9uKGEs
-Yil7dmFyIHQscwp0cnl7dD1hLmRlY29kZShiKQpyZXR1cm4gdH1jYXRjaChzKXtILlJ1KHMpfXJldHVy
-biBudWxsfSwKQWo6ZnVuY3Rpb24oYSl7dmFyIHQscz1hLmxlbmd0aC0yCmZvcih0PTA7dDxzOysrdClp
-ZihhW3RdPT09MjM3KWlmKChhW3QrMV0mMjI0KT09PTE2MClyZXR1cm4hMApyZXR1cm4hMX0sCmNQOmZ1
-bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIKZm9yKHQ9Si5VNihhKSxzPWI7czxjOysrcyl7cj10LnEoYSxz
-KQppZih0eXBlb2YgciE9PSJudW1iZXIiKXJldHVybiByLnpNKCkKaWYoKHImMTI3KSE9PXIpcmV0dXJu
-IHMtYn1yZXR1cm4gYy1ifSwKeE06ZnVuY3Rpb24oYSxiLGMsZCxlLGYpe2lmKEMuam4uelkoZiw0KSE9
-PTApdGhyb3cgSC5iKFAucnIoIkludmFsaWQgYmFzZTY0IHBhZGRpbmcsIHBhZGRlZCBsZW5ndGggbXVz
-dCBiZSBtdWx0aXBsZSBvZiBmb3VyLCBpcyAiK2YsYSxjKSkKaWYoZCtlIT09Zil0aHJvdyBILmIoUC5y
-cigiSW52YWxpZCBiYXNlNjQgcGFkZGluZywgJz0nIG5vdCBhdCB0aGUgZW5kIixhLGIpKQppZihlPjIp
-dGhyb3cgSC5iKFAucnIoIkludmFsaWQgYmFzZTY0IHBhZGRpbmcsIG1vcmUgdGhhbiB0d28gJz0nIGNo
-YXJhY3RlcnMiLGEsYikpfSwKdXc6ZnVuY3Rpb24gdXcoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlz
-LmM9bnVsbH0sCmk4OmZ1bmN0aW9uIGk4KGEpe3RoaXMuYT1hfSwKcGc6ZnVuY3Rpb24gcGcoKXt9LApD
-VjpmdW5jdGlvbiBDVigpe30sClU4OmZ1bmN0aW9uIFU4KCl7fSwKVWs6ZnVuY3Rpb24gVWsoKXt9LAp3
-STpmdW5jdGlvbiB3SSgpe30sClppOmZ1bmN0aW9uIFppKCl7fSwKYnk6ZnVuY3Rpb24gYnkoKXt9LApN
-eDpmdW5jdGlvbiBNeChhKXt0aGlzLmE9YX0sCnU1OmZ1bmN0aW9uIHU1KCl7fSwKRTM6ZnVuY3Rpb24g
-RTMoKXt9LApSdzpmdW5jdGlvbiBSdyhhKXt0aGlzLmI9MAp0aGlzLmM9YX0sCkdZOmZ1bmN0aW9uIEdZ
-KGEpe3RoaXMuYT1hfSwKYno6ZnVuY3Rpb24gYnooYSxiKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8u
-Yz0hMApfLmY9Xy5lPV8uZD0wfSwKUUE6ZnVuY3Rpb24oYSxiKXt2YXIgdD1ILkhwKGEsYikKaWYodCE9
-bnVsbClyZXR1cm4gdAp0aHJvdyBILmIoUC5ycihhLG51bGwsbnVsbCkpfSwKb3M6ZnVuY3Rpb24oYSl7
-aWYoYSBpbnN0YW5jZW9mIEguVHApcmV0dXJuIGEuWigwKQpyZXR1cm4iSW5zdGFuY2Ugb2YgJyIrSC5k
-KEgubGgoYSkpKyInIn0sCk84OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHM9Si5RaShhLGQpCmlmKGEh
-PT0wJiZiIT1udWxsKWZvcih0PTA7dDxzLmxlbmd0aDsrK3QpQy5ObS5ZKHMsdCxiKQpyZXR1cm4gc30s
-CkNIOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzPUguVk0oW10sYy5DKCJqZDwwPiIpKQpmb3IodD1KLklU
-KGEpO3QuRigpOylDLk5tLmkocyxjLmEodC5nbCgpKSkKaWYoYilyZXR1cm4gcwpyZXR1cm4gSi5FcChz
-LGMpfSwKZEg6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscz1KLktoKGEsZCkKZm9yKHQ9MDt0PGE7Kyt0
-KUMuTm0uWShzLHQsYi4kMSh0KSkKcmV0dXJuIHN9LApBRjpmdW5jdGlvbihhLGIpe3JldHVybiBKLnVu
-KFAuQ0goYSwhMSxiKSl9LApITTpmdW5jdGlvbihhLGIsYyl7dmFyIHQscz11LnQKaWYocy5iKGEpKXt0
-PWEubGVuZ3RoCmM9UC5qQihiLGMsdCkKcmV0dXJuIEguZVQoYj4wfHxjPHQ/cy5hKEMuTm0uRDYoYSxi
-LGMpKTphKX1pZih1LmJtLmIoYSkpcmV0dXJuIEguZncoYSxiLFAuakIoYixjLGEubGVuZ3RoKSkKcmV0
-dXJuIFAuYncoYSxiLGMpfSwKT286ZnVuY3Rpb24oYSl7cmV0dXJuIEguTHcoYSl9LApidzpmdW5jdGlv
-bihhLGIsYyl7dmFyIHQscyxyLHEscD1udWxsCmlmKGI8MCl0aHJvdyBILmIoUC5URShiLDAsSi5IKGEp
-LHAscCkpCnQ9Yz09bnVsbAppZighdCYmYzxiKXRocm93IEguYihQLlRFKGMsYixKLkgoYSkscCxwKSkK
-cz1KLklUKGEpCmZvcihyPTA7cjxiOysrcilpZighcy5GKCkpdGhyb3cgSC5iKFAuVEUoYiwwLHIscCxw
-KSkKcT1bXQppZih0KWZvcig7cy5GKCk7KXEucHVzaChzLmdsKCkpCmVsc2UgZm9yKHI9YjtyPGM7Kyty
-KXtpZighcy5GKCkpdGhyb3cgSC5iKFAuVEUoYyxiLHIscCxwKSkKcS5wdXNoKHMuZ2woKSl9cmV0dXJu
-IEguZVQocSl9LApudTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEguVlIoYSxILnY0KGEsITEsITAsITEs
-ITEsITEpKX0sCnZnOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1KLklUKGIpCmlmKCF0LkYoKSlyZXR1cm4g
-YQppZihjLmxlbmd0aD09PTApe2RvIGErPUguZCh0LmdsKCkpCndoaWxlKHQuRigpKX1lbHNle2ErPUgu
-ZCh0LmdsKCkpCmZvcig7dC5GKCk7KWE9YStjK0guZCh0LmdsKCkpfXJldHVybiBhfSwKbHI6ZnVuY3Rp
-b24oYSxiLGMsZCl7cmV0dXJuIG5ldyBQLm1wKGEsYixjLGQpfSwKdW86ZnVuY3Rpb24oKXt2YXIgdD1I
-Lk0wKCkKaWYodCE9bnVsbClyZXR1cm4gUC5oSyh0KQp0aHJvdyBILmIoUC5MNCgiJ1VyaS5iYXNlJyBp
-cyBub3Qgc3VwcG9ydGVkIikpfSwKZVA6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyLHEscCxvLG49
-IjAxMjM0NTY3ODlBQkNERUYiCmlmKGM9PT1DLnhNKXt0PSQuejQoKS5iCmlmKHR5cGVvZiBiIT0ic3Ry
-aW5nIilILnZoKEguSShiKSkKdD10LnRlc3QoYil9ZWxzZSB0PSExCmlmKHQpcmV0dXJuIGIKSC5MaChj
-KS5DKCJVay5TIikuYShiKQpzPWMuZ1pFKCkuV0ooYikKZm9yKHQ9cy5sZW5ndGgscj0wLHE9IiI7cjx0
-Oysrcil7cD1zW3JdCmlmKHA8MTI4KXtvPXA+Pj40CmlmKG8+PTgpcmV0dXJuIEguayhhLG8pCm89KGFb
-b10mMTw8KHAmMTUpKSE9PTB9ZWxzZSBvPSExCmlmKG8pcSs9SC5MdyhwKQplbHNlIHE9ZCYmcD09PTMy
-P3ErIisiOnErIiUiK25bcD4+PjQmMTVdK25bcCYxNV19cmV0dXJuIHEuY2hhckNvZGVBdCgwKT09MD9x
-OnF9LApHcTpmdW5jdGlvbihhKXt2YXIgdD1NYXRoLmFicyhhKSxzPWE8MD8iLSI6IiIKaWYodD49MTAw
-MClyZXR1cm4iIithCmlmKHQ+PTEwMClyZXR1cm4gcysiMCIrdAppZih0Pj0xMClyZXR1cm4gcysiMDAi
-K3QKcmV0dXJuIHMrIjAwMCIrdH0sClZ4OmZ1bmN0aW9uKGEpe2lmKGE+PTEwMClyZXR1cm4iIithCmlm
-KGE+PTEwKXJldHVybiIwIithCnJldHVybiIwMCIrYX0sCmgwOmZ1bmN0aW9uKGEpe2lmKGE+PTEwKXJl
-dHVybiIiK2EKcmV0dXJuIjAiK2F9LApoOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyInx8
-SC5yUShhKXx8bnVsbD09YSlyZXR1cm4gSi5BYyhhKQppZih0eXBlb2YgYT09InN0cmluZyIpcmV0dXJu
-IEpTT04uc3RyaW5naWZ5KGEpCnJldHVybiBQLm9zKGEpfSwKaFY6ZnVuY3Rpb24oYSl7cmV0dXJuIG5l
-dyBQLkM2KGEpfSwKeFk6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLkFUKCExLG51bGwsbnVsbCxhKX0s
-CkwzOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gbmV3IFAuQVQoITAsYSxiLGMpfSwKVUk6ZnVuY3Rpb24o
-YSxiLGMpe2lmKGE9PW51bGwpdGhyb3cgSC5iKG5ldyBQLkFUKCExLG51bGwsYiwiTXVzdCBub3QgYmUg
-bnVsbCIpKQpyZXR1cm4gYX0sCk83OmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBQLmJKKG51bGwsbnVs
-bCwhMCxhLGIsIlZhbHVlIG5vdCBpbiByYW5nZSIpfSwKVEU6ZnVuY3Rpb24oYSxiLGMsZCxlKXtyZXR1
-cm4gbmV3IFAuYkooYixjLCEwLGEsZCwiSW52YWxpZCB2YWx1ZSIpfSwKd0E6ZnVuY3Rpb24oYSxiLGMs
-ZCl7aWYoYTxifHxhPmMpdGhyb3cgSC5iKFAuVEUoYSxiLGMsZCxudWxsKSkKcmV0dXJuIGF9LApqQjpm
-dW5jdGlvbihhLGIsYyl7aWYoMD5hfHxhPmMpdGhyb3cgSC5iKFAuVEUoYSwwLGMsInN0YXJ0IixudWxs
-KSkKaWYoYiE9bnVsbCl7aWYoYT5ifHxiPmMpdGhyb3cgSC5iKFAuVEUoYixhLGMsImVuZCIsbnVsbCkp
-CnJldHVybiBifXJldHVybiBjfSwKazE6ZnVuY3Rpb24oYSxiKXtpZihhPDApdGhyb3cgSC5iKFAuVEUo
-YSwwLG51bGwsYixudWxsKSkKcmV0dXJuIGF9LAp0OmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHQ9SC5X
-WShlPT1udWxsP0ouSChiKTplKQpyZXR1cm4gbmV3IFAuZVkodCwhMCxhLGMsIkluZGV4IG91dCBvZiBy
-YW5nZSIpfSwKTDQ6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLnViKGEpfSwKbjpmdW5jdGlvbihhKXty
-ZXR1cm4gbmV3IFAuZHMoYSl9LApQVjpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAubGooYSl9LAphNDpm
-dW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuVVYoYSl9LApycjpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIG5l
-dyBQLmFFKGEsYixjKX0sCmhLOmZ1bmN0aW9uKGE0KXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGks
-aCxnLGYsZSxkLGMsYixhLGEwLGExLGEyPW51bGwsYTM9YTQubGVuZ3RoCmlmKGEzPj01KXt0PSgoSi5R
-eihhNCw0KV41OCkqM3xDLnhCLlcoYTQsMCleMTAwfEMueEIuVyhhNCwxKV45N3xDLnhCLlcoYTQsMile
-MTE2fEMueEIuVyhhNCwzKV45Nyk+Pj4wCmlmKHQ9PT0wKXJldHVybiBQLktEKGEzPGEzP0MueEIuTmoo
-YTQsMCxhMyk6YTQsNSxhMikuZ2xSKCkKZWxzZSBpZih0PT09MzIpcmV0dXJuIFAuS0QoQy54Qi5Oaihh
-NCw1LGEzKSwwLGEyKS5nbFIoKX1zPVAuTzgoOCwwLCExLHUucSkKQy5ObS5ZKHMsMCwwKQpDLk5tLlko
-cywxLC0xKQpDLk5tLlkocywyLC0xKQpDLk5tLlkocyw3LC0xKQpDLk5tLlkocywzLDApCkMuTm0uWShz
-LDQsMCkKQy5ObS5ZKHMsNSxhMykKQy5ObS5ZKHMsNixhMykKaWYoUC5VQihhNCwwLGEzLDAscyk+PTE0
-KUMuTm0uWShzLDcsYTMpCmlmKDE+PXMubGVuZ3RoKXJldHVybiBILmsocywxKQpyPXNbMV0KaWYocj49
-MClpZihQLlVCKGE0LDAsciwyMCxzKT09PTIwKXtpZig3Pj1zLmxlbmd0aClyZXR1cm4gSC5rKHMsNykK
-c1s3XT1yfXE9cy5sZW5ndGgKaWYoMj49cSlyZXR1cm4gSC5rKHMsMikKcD1zWzJdKzEKaWYoMz49cSly
-ZXR1cm4gSC5rKHMsMykKbz1zWzNdCmlmKDQ+PXEpcmV0dXJuIEguayhzLDQpCm49c1s0XQppZig1Pj1x
-KXJldHVybiBILmsocyw1KQptPXNbNV0KaWYoNj49cSlyZXR1cm4gSC5rKHMsNikKbD1zWzZdCmlmKGw8
-bSltPWwKaWYobjxwKW49bQplbHNlIGlmKG48PXIpbj1yKzEKaWYobzxwKW89bgppZig3Pj1xKXJldHVy
-biBILmsocyw3KQprPXNbN108MAppZihrKWlmKHA+ciszKXtqPWEyCms9ITF9ZWxzZXtxPW8+MAppZihx
-JiZvKzE9PT1uKXtqPWEyCms9ITF9ZWxzZXtpZighKG08YTMmJm09PT1uKzImJkoucTAoYTQsIi4uIixu
-KSkpaT1tPm4rMiYmSi5xMChhNCwiLy4uIixtLTMpCmVsc2UgaT0hMAppZihpKXtqPWEyCms9ITF9ZWxz
-ZXtpZihyPT09NClpZihKLnEwKGE0LCJmaWxlIiwwKSl7aWYocDw9MCl7aWYoIUMueEIuUWkoYTQsIi8i
-LG4pKXtoPSJmaWxlOi8vLyIKdD0zfWVsc2V7aD0iZmlsZTovLyIKdD0yfWE0PWgrQy54Qi5OaihhNCxu
-LGEzKQpyLT0wCnE9dC0wCm0rPXEKbCs9cQphMz1hNC5sZW5ndGgKcD03Cm89NwpuPTd9ZWxzZSBpZihu
-PT09bSl7KytsCmc9bSsxCmE0PUMueEIuaTcoYTQsbixtLCIvIik7KythMwptPWd9aj0iZmlsZSJ9ZWxz
-ZSBpZihDLnhCLlFpKGE0LCJodHRwIiwwKSl7aWYocSYmbyszPT09biYmQy54Qi5RaShhNCwiODAiLG8r
-MSkpe2wtPTMKZj1uLTMKbS09MwphND1DLnhCLmk3KGE0LG8sbiwiIikKYTMtPTMKbj1mfWo9Imh0dHAi
-fWVsc2Ugaj1hMgplbHNlIGlmKHI9PT01JiZKLnEwKGE0LCJodHRwcyIsMCkpe2lmKHEmJm8rND09PW4m
-JkoucTAoYTQsIjQ0MyIsbysxKSl7bC09NApmPW4tNAptLT00CmE0PUouZGcoYTQsbyxuLCIiKQphMy09
-MwpuPWZ9aj0iaHR0cHMifWVsc2Ugaj1hMgprPSEwfX19ZWxzZSBqPWEyCmlmKGspe3E9YTQubGVuZ3Ro
-CmlmKGEzPHEpe2E0PUoubGQoYTQsMCxhMykKci09MApwLT0wCm8tPTAKbi09MAptLT0wCmwtPTB9cmV0
-dXJuIG5ldyBQLlVmKGE0LHIscCxvLG4sbSxsLGopfWlmKGo9PW51bGwpaWYocj4wKWo9UC5QaShhNCww
-LHIpCmVsc2V7aWYocj09PTApUC5SMyhhNCwwLCJJbnZhbGlkIGVtcHR5IHNjaGVtZSIpCmo9IiJ9aWYo
-cD4wKXtlPXIrMwpkPWU8cD9QLnpSKGE0LGUscC0xKToiIgpjPVAuT2UoYTQscCxvLCExKQpxPW8rMQpp
-ZihxPG4pe2I9SC5IcChKLmxkKGE0LHEsbiksYTIpCmE9UC53QihiPT1udWxsP0gudmgoUC5ycigiSW52
-YWxpZCBwb3J0IixhNCxxKSk6YixqKX1lbHNlIGE9YTJ9ZWxzZXthPWEyCmM9YQpkPSIifWEwPVAua2Eo
-YTQsbixtLGEyLGosYyE9bnVsbCkKYTE9bTxsP1AubGUoYTQsbSsxLGwsYTIpOmEyCnJldHVybiBuZXcg
-UC5EbihqLGQsYyxhLGEwLGExLGw8YTM/UC50RyhhNCxsKzEsYTMpOmEyKX0sCk10OmZ1bmN0aW9uKGEp
-e0guYyhhKQpyZXR1cm4gUC5rdShhLDAsYS5sZW5ndGgsQy54TSwhMSl9LApXWDpmdW5jdGlvbihhKXt2
-YXIgdD11Lk4KcmV0dXJuIEMuTm0uTjAoSC5WTShhLnNwbGl0KCImIiksdS5zKSxQLkZsKHQsdCksbmV3
-IFAubjEoQy54TSksdS5mKX0sCkhoOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscSxwLG8sbixtPSJJ
-UHY0IGFkZHJlc3Mgc2hvdWxkIGNvbnRhaW4gZXhhY3RseSA0IHBhcnRzIixsPSJlYWNoIHBhcnQgbXVz
-dCBiZSBpbiB0aGUgcmFuZ2UgMC4uMjU1IixrPW5ldyBQLmNTKGEpLGo9bmV3IFVpbnQ4QXJyYXkoNCkK
-Zm9yKHQ9ai5sZW5ndGgscz1iLHI9cyxxPTA7czxjOysrcyl7cD1DLnhCLm0oYSxzKQppZihwIT09NDYp
-e2lmKChwXjQ4KT45KWsuJDIoImludmFsaWQgY2hhcmFjdGVyIixzKX1lbHNle2lmKHE9PT0zKWsuJDIo
-bSxzKQpvPVAuUUEoQy54Qi5OaihhLHIscyksbnVsbCkKaWYodHlwZW9mIG8hPT0ibnVtYmVyIilyZXR1
-cm4gby5vcygpCmlmKG8+MjU1KWsuJDIobCxyKQpuPXErMQppZihxPj10KXJldHVybiBILmsoaixxKQpq
-W3FdPW8Kcj1zKzEKcT1ufX1pZihxIT09MylrLiQyKG0sYykKbz1QLlFBKEMueEIuTmooYSxyLGMpLG51
-bGwpCmlmKHR5cGVvZiBvIT09Im51bWJlciIpcmV0dXJuIG8ub3MoKQppZihvPjI1NSlrLiQyKGwscikK
-aWYocT49dClyZXR1cm4gSC5rKGoscSkKaltxXT1vCnJldHVybiBqfSwKZWc6ZnVuY3Rpb24oYSxiLGEw
-KXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGksaCxnLGYsZSxkPW5ldyBQLlZDKGEpLGM9bmV3IFAu
-SlQoZCxhKQppZihhLmxlbmd0aDwyKWQuJDEoImFkZHJlc3MgaXMgdG9vIHNob3J0IikKdD1ILlZNKFtd
-LHUudCkKZm9yKHM9YixyPXMscT0hMSxwPSExO3M8YTA7KytzKXtvPUMueEIubShhLHMpCmlmKG89PT01
-OCl7aWYocz09PWIpeysrcwppZihDLnhCLm0oYSxzKSE9PTU4KWQuJDIoImludmFsaWQgc3RhcnQgY29s
-b24uIixzKQpyPXN9aWYocz09PXIpe2lmKHEpZC4kMigib25seSBvbmUgd2lsZGNhcmQgYDo6YCBpcyBh
-bGxvd2VkIixzKQpDLk5tLmkodCwtMSkKcT0hMH1lbHNlIEMuTm0uaSh0LGMuJDIocixzKSkKcj1zKzF9
-ZWxzZSBpZihvPT09NDYpcD0hMH1pZih0Lmxlbmd0aD09PTApZC4kMSgidG9vIGZldyBwYXJ0cyIpCm49
-cj09PWEwCm09Qy5ObS5ncloodCkKaWYobiYmbSE9PS0xKWQuJDIoImV4cGVjdGVkIGEgcGFydCBhZnRl
-ciBsYXN0IGA6YCIsYTApCmlmKCFuKWlmKCFwKUMuTm0uaSh0LGMuJDIocixhMCkpCmVsc2V7bD1QLkho
-KGEscixhMCkKQy5ObS5pKHQsKGxbMF08PDh8bFsxXSk+Pj4wKQpDLk5tLmkodCwobFsyXTw8OHxsWzNd
-KT4+PjApfWlmKHEpe2lmKHQubGVuZ3RoPjcpZC4kMSgiYW4gYWRkcmVzcyB3aXRoIGEgd2lsZGNhcmQg
-bXVzdCBoYXZlIGxlc3MgdGhhbiA3IHBhcnRzIil9ZWxzZSBpZih0Lmxlbmd0aCE9PTgpZC4kMSgiYW4g
-YWRkcmVzcyB3aXRob3V0IGEgd2lsZGNhcmQgbXVzdCBjb250YWluIGV4YWN0bHkgOCBwYXJ0cyIpCms9
-bmV3IFVpbnQ4QXJyYXkoMTYpCmZvcihtPXQubGVuZ3RoLGo9ay5sZW5ndGgsaT05LW0scz0wLGg9MDtz
-PG07KytzKXtnPXRbc10KaWYoZz09PS0xKWZvcihmPTA7ZjxpOysrZil7aWYoaDwwfHxoPj1qKXJldHVy
-biBILmsoayxoKQprW2hdPTAKZT1oKzEKaWYoZT49ailyZXR1cm4gSC5rKGssZSkKa1tlXT0wCmgrPTJ9
-ZWxzZXtlPUMuam4ud0coZyw4KQppZihoPDB8fGg+PWopcmV0dXJuIEguayhrLGgpCmtbaF09ZQplPWgr
-MQppZihlPj1qKXJldHVybiBILmsoayxlKQprW2VdPWcmMjU1CmgrPTJ9fXJldHVybiBrfSwKS0w6ZnVu
-Y3Rpb24oYSxiLGMsZCxlLGYsZyl7dmFyIHQscyxyLHEscCxvCmY9Zj09bnVsbD8iIjpQLlBpKGYsMCxm
-Lmxlbmd0aCkKZz1QLnpSKGcsMCxnPT1udWxsPzA6Zy5sZW5ndGgpCmE9UC5PZShhLDAsYT09bnVsbD8w
-OmEubGVuZ3RoLCExKQp0PVAubGUobnVsbCwwLDAsZSkKcz1QLnRHKG51bGwsMCwwKQpkPVAud0IoZCxm
-KQpyPWY9PT0iZmlsZSIKaWYoYT09bnVsbClxPWcubGVuZ3RoIT09MHx8ZCE9bnVsbHx8cgplbHNlIHE9
-ITEKaWYocSlhPSIiCnE9YT09bnVsbApwPSFxCmI9UC5rYShiLDAsYj09bnVsbD8wOmIubGVuZ3RoLGMs
-ZixwKQpvPWYubGVuZ3RoPT09MAppZihvJiZxJiYhQy54Qi5uKGIsIi8iKSliPVAud0YoYiwhb3x8cCkK
-ZWxzZSBiPVAueGUoYikKcmV0dXJuIG5ldyBQLkRuKGYsZyxxJiZDLnhCLm4oYiwiLy8iKT8iIjphLGQs
-Yix0LHMpfSwKd0s6ZnVuY3Rpb24oYSl7aWYoYT09PSJodHRwIilyZXR1cm4gODAKaWYoYT09PSJodHRw
-cyIpcmV0dXJuIDQ0MwpyZXR1cm4gMH0sClIzOmZ1bmN0aW9uKGEsYixjKXt0aHJvdyBILmIoUC5ycihj
-LGEsYikpfSwKWGQ6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixpPW51
-bGwsaD1iLmxlbmd0aAppZihoIT09MCl7cj0wCndoaWxlKCEwKXtpZighKHI8aCkpe3Q9IiIKcz0wCmJy
-ZWFrfWlmKEMueEIuVyhiLHIpPT09NjQpe3Q9Qy54Qi5OaihiLDAscikKcz1yKzEKYnJlYWt9KytyfWlm
-KHM8aCYmQy54Qi5XKGIscyk9PT05MSl7Zm9yKHE9cyxwPS0xO3E8aDsrK3Epe289Qy54Qi5XKGIscSkK
-aWYobz09PTM3JiZwPDApe249Qy54Qi5RaShiLCIyNSIscSsxKT9xKzI6cQpwPXEKcT1ufWVsc2UgaWYo
-bz09PTkzKWJyZWFrfWlmKHE9PT1oKXRocm93IEguYihQLnJyKCJJbnZhbGlkIElQdjYgaG9zdCBlbnRy
-eS4iLGIscykpCm09cDwwP3E6cApQLmVnKGIscysxLG0pOysrcQppZihxIT09aCYmQy54Qi5XKGIscSkh
-PT01OCl0aHJvdyBILmIoUC5ycigiSW52YWxpZCBlbmQgb2YgYXV0aG9yaXR5IixiLHEpKX1lbHNlIHE9
-cwp3aGlsZSghMCl7aWYoIShxPGgpKXtsPWkKYnJlYWt9aWYoQy54Qi5XKGIscSk9PT01OCl7az1DLnhC
-LkcoYixxKzEpCmw9ay5sZW5ndGghPT0wP1AuUUEoayxpKTppCmJyZWFrfSsrcX1qPUMueEIuTmooYixz
-LHEpfWVsc2V7bD1pCmo9bAp0PSIifXJldHVybiBQLktMKGosaSxILlZNKGMuc3BsaXQoIi8iKSx1LnMp
-LGwsZCxhLHQpfSwKa0U6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwCmZvcih0PWEubGVuZ3RoLHM9
-MDtzPHQ7KytzKXtyPWFbc10Kci50b1N0cmluZwpxPUouVTYocikKcD1xLmdBKHIpCmlmKDA+cClILnZo
-KFAuVEUoMCwwLHEuZ0EociksbnVsbCxudWxsKSkKaWYoSC5tMihyLCIvIiwwKSl7dD1QLkw0KCJJbGxl
-Z2FsIHBhdGggY2hhcmFjdGVyICIrSC5kKHIpKQp0aHJvdyBILmIodCl9fX0sCkhOOmZ1bmN0aW9uKGEs
-YixjKXt2YXIgdCxzLHIKZm9yKHQ9SC5xQyhhLGMsbnVsbCxILnQ2KGEpLmMpLHQ9bmV3IEguYTcodCx0
-LmdBKHQpLHQuJHRpLkMoImE3PGFMLkU+IikpO3QuRigpOyl7cz10LmQKcj1QLm51KCdbIiovOjw+P1xc
-XFx8XScpCnMudG9TdHJpbmcKaWYoSC5tMihzLHIsMCkpe3Q9UC5MNCgiSWxsZWdhbCBjaGFyYWN0ZXIg
-aW4gcGF0aDogIitzKQp0aHJvdyBILmIodCl9fX0sCnJnOmZ1bmN0aW9uKGEsYil7dmFyIHQKaWYoISg2
-NTw9YSYmYTw9OTApKXQ9OTc8PWEmJmE8PTEyMgplbHNlIHQ9ITAKaWYodClyZXR1cm4KdD1QLkw0KCJJ
-bGxlZ2FsIGRyaXZlIGxldHRlciAiK1AuT28oYSkpCnRocm93IEguYih0KX0sCndCOmZ1bmN0aW9uKGEs
-Yil7aWYoYSE9bnVsbCYmYT09PVAud0soYikpcmV0dXJuIG51bGwKcmV0dXJuIGF9LApPZTpmdW5jdGlv
-bihhLGIsYyxkKXt2YXIgdCxzLHIscSxwLG8KaWYoYT09bnVsbClyZXR1cm4gbnVsbAppZihiPT09Yyly
-ZXR1cm4iIgppZihDLnhCLm0oYSxiKT09PTkxKXt0PWMtMQppZihDLnhCLm0oYSx0KSE9PTkzKVAuUjMo
-YSxiLCJNaXNzaW5nIGVuZCBgXWAgdG8gbWF0Y2ggYFtgIGluIGhvc3QiKQpzPWIrMQpyPVAudG8oYSxz
-LHQpCmlmKHI8dCl7cT1yKzEKcD1QLk9BKGEsQy54Qi5RaShhLCIyNSIscSk/ciszOnEsdCwiJTI1Iil9
-ZWxzZSBwPSIiClAuZWcoYSxzLHIpCnJldHVybiBDLnhCLk5qKGEsYixyKS50b0xvd2VyQ2FzZSgpK3Ar
-Il0ifWZvcihvPWI7bzxjOysrbylpZihDLnhCLm0oYSxvKT09PTU4KXtyPUMueEIuWFUoYSwiJSIsYikK
-cj1yPj1iJiZyPGM/cjpjCmlmKHI8Yyl7cT1yKzEKcD1QLk9BKGEsQy54Qi5RaShhLCIyNSIscSk/cisz
-OnEsYywiJTI1Iil9ZWxzZSBwPSIiClAuZWcoYSxiLHIpCnJldHVybiJbIitDLnhCLk5qKGEsYixyKStw
-KyJdIn1yZXR1cm4gUC5PTChhLGIsYyl9LAp0bzpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9Qy54Qi5YVShh
-LCIlIixiKQpyZXR1cm4gdD49YiYmdDxjP3Q6Y30sCk9BOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMs
-cixxLHAsbyxuLG0sbCxrLGo9ZCE9PSIiP25ldyBQLlJuKGQpOm51bGwKZm9yKHQ9YixzPXQscj0hMDt0
-PGM7KXtxPUMueEIubShhLHQpCmlmKHE9PT0zNyl7cD1QLnJ2KGEsdCwhMCkKbz1wPT1udWxsCmlmKG8m
-JnIpe3QrPTMKY29udGludWV9aWYoaj09bnVsbClqPW5ldyBQLlJuKCIiKQpuPWouYSs9Qy54Qi5Oaihh
-LHMsdCkKaWYobylwPUMueEIuTmooYSx0LHQrMykKZWxzZSBpZihwPT09IiUiKVAuUjMoYSx0LCJab25l
-SUQgc2hvdWxkIG5vdCBjb250YWluICUgYW55bW9yZSIpCmouYT1uK3AKdCs9MwpzPXQKcj0hMH1lbHNl
-e2lmKHE8MTI3KXtvPXE+Pj40CmlmKG8+PTgpcmV0dXJuIEguayhDLkYzLG8pCm89KEMuRjNbb10mMTw8
-KHEmMTUpKSE9PTB9ZWxzZSBvPSExCmlmKG8pe2lmKHImJjY1PD1xJiY5MD49cSl7aWYoaj09bnVsbClq
-PW5ldyBQLlJuKCIiKQppZihzPHQpe2ouYSs9Qy54Qi5OaihhLHMsdCkKcz10fXI9ITF9Kyt0fWVsc2V7
-aWYoKHEmNjQ1MTIpPT09NTUyOTYmJnQrMTxjKXttPUMueEIubShhLHQrMSkKaWYoKG0mNjQ1MTIpPT09
-NTYzMjApe3E9NjU1MzZ8KHEmMTAyMyk8PDEwfG0mMTAyMwpsPTJ9ZWxzZSBsPTF9ZWxzZSBsPTEKaz1D
-LnhCLk5qKGEscyx0KQppZihqPT1udWxsKXtqPW5ldyBQLlJuKCIiKQpvPWp9ZWxzZSBvPWoKby5hKz1r
-Cm8uYSs9UC56WChxKQp0Kz1sCnM9dH19fWlmKGo9PW51bGwpcmV0dXJuIEMueEIuTmooYSxiLGMpCmlm
-KHM8YylqLmErPUMueEIuTmooYSxzLGMpCm89ai5hCnJldHVybiBvLmNoYXJDb2RlQXQoMCk9PTA/bzpv
-fSwKT0w6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGoKZm9yKHQ9YixzPXQs
-cj1udWxsLHE9ITA7dDxjOyl7cD1DLnhCLm0oYSx0KQppZihwPT09Mzcpe289UC5ydihhLHQsITApCm49
-bz09bnVsbAppZihuJiZxKXt0Kz0zCmNvbnRpbnVlfWlmKHI9PW51bGwpcj1uZXcgUC5SbigiIikKbT1D
-LnhCLk5qKGEscyx0KQpsPXIuYSs9IXE/bS50b0xvd2VyQ2FzZSgpOm0KaWYobil7bz1DLnhCLk5qKGEs
-dCx0KzMpCms9M31lbHNlIGlmKG89PT0iJSIpe289IiUyNSIKaz0xfWVsc2Ugaz0zCnIuYT1sK28KdCs9
-awpzPXQKcT0hMH1lbHNle2lmKHA8MTI3KXtuPXA+Pj40CmlmKG4+PTgpcmV0dXJuIEguayhDLmVhLG4p
-Cm49KEMuZWFbbl0mMTw8KHAmMTUpKSE9PTB9ZWxzZSBuPSExCmlmKG4pe2lmKHEmJjY1PD1wJiY5MD49
-cCl7aWYocj09bnVsbClyPW5ldyBQLlJuKCIiKQppZihzPHQpe3IuYSs9Qy54Qi5OaihhLHMsdCkKcz10
-fXE9ITF9Kyt0fWVsc2V7aWYocDw9OTMpe249cD4+PjQKaWYobj49OClyZXR1cm4gSC5rKEMuYWssbikK
-bj0oQy5ha1tuXSYxPDwocCYxNSkpIT09MH1lbHNlIG49ITEKaWYobilQLlIzKGEsdCwiSW52YWxpZCBj
-aGFyYWN0ZXIiKQplbHNle2lmKChwJjY0NTEyKT09PTU1Mjk2JiZ0KzE8Yyl7aj1DLnhCLm0oYSx0KzEp
-CmlmKChqJjY0NTEyKT09PTU2MzIwKXtwPTY1NTM2fChwJjEwMjMpPDwxMHxqJjEwMjMKaz0yfWVsc2Ug
-az0xfWVsc2Ugaz0xCm09Qy54Qi5OaihhLHMsdCkKaWYoIXEpbT1tLnRvTG93ZXJDYXNlKCkKaWYocj09
-bnVsbCl7cj1uZXcgUC5SbigiIikKbj1yfWVsc2Ugbj1yCm4uYSs9bQpuLmErPVAuelgocCkKdCs9awpz
-PXR9fX19aWYocj09bnVsbClyZXR1cm4gQy54Qi5OaihhLGIsYykKaWYoczxjKXttPUMueEIuTmooYSxz
-LGMpCnIuYSs9IXE/bS50b0xvd2VyQ2FzZSgpOm19bj1yLmEKcmV0dXJuIG4uY2hhckNvZGVBdCgwKT09
-MD9uOm59LApQaTpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEKaWYoYj09PWMpcmV0dXJuIiIKaWYo
-IVAuRXQoSi5yWShhKS5XKGEsYikpKVAuUjMoYSxiLCJTY2hlbWUgbm90IHN0YXJ0aW5nIHdpdGggYWxw
-aGFiZXRpYyBjaGFyYWN0ZXIiKQpmb3IodD1iLHM9ITE7dDxjOysrdCl7cj1DLnhCLlcoYSx0KQppZihy
-PDEyOCl7cT1yPj4+NAppZihxPj04KXJldHVybiBILmsoQy5tSyxxKQpxPShDLm1LW3FdJjE8PChyJjE1
-KSkhPT0wfWVsc2UgcT0hMQppZighcSlQLlIzKGEsdCwiSWxsZWdhbCBzY2hlbWUgY2hhcmFjdGVyIikK
-aWYoNjU8PXImJnI8PTkwKXM9ITB9YT1DLnhCLk5qKGEsYixjKQpyZXR1cm4gUC5ZYShzP2EudG9Mb3dl
-ckNhc2UoKTphKX0sCllhOmZ1bmN0aW9uKGEpe2lmKGE9PT0iaHR0cCIpcmV0dXJuImh0dHAiCmlmKGE9
-PT0iZmlsZSIpcmV0dXJuImZpbGUiCmlmKGE9PT0iaHR0cHMiKXJldHVybiJodHRwcyIKaWYoYT09PSJw
-YWNrYWdlIilyZXR1cm4icGFja2FnZSIKcmV0dXJuIGF9LAp6UjpmdW5jdGlvbihhLGIsYyl7aWYoYT09
-bnVsbClyZXR1cm4iIgpyZXR1cm4gUC5QSShhLGIsYyxDLnRvLCExKX0sCmthOmZ1bmN0aW9uKGEsYixj
-LGQsZSxmKXt2YXIgdCxzLHI9ZT09PSJmaWxlIixxPXJ8fGYKaWYoYT09bnVsbCl7aWYoZD09bnVsbCly
-ZXR1cm4gcj8iLyI6IiIKdD1ILnQ2KGQpCnM9bmV3IEgubEooZCx0LkMoInFVKDEpIikuYShuZXcgUC5S
-WigpKSx0LkMoImxKPDEscVU+IikpLnpWKDAsIi8iKX1lbHNlIGlmKGQhPW51bGwpdGhyb3cgSC5iKFAu
-eFkoIkJvdGggcGF0aCBhbmQgcGF0aFNlZ21lbnRzIHNwZWNpZmllZCIpKQplbHNlIHM9UC5QSShhLGIs
-YyxDLldkLCEwKQppZihzLmxlbmd0aD09PTApe2lmKHIpcmV0dXJuIi8ifWVsc2UgaWYocSYmIUMueEIu
-bihzLCIvIikpcz0iLyIrcwpyZXR1cm4gUC5KcihzLGUsZil9LApKcjpmdW5jdGlvbihhLGIsYyl7dmFy
-IHQ9Yi5sZW5ndGg9PT0wCmlmKHQmJiFjJiYhQy54Qi5uKGEsIi8iKSlyZXR1cm4gUC53RihhLCF0fHxj
-KQpyZXR1cm4gUC54ZShhKX0sCmxlOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHM9e30KaWYoYSE9bnVs
-bCl7aWYoZCE9bnVsbCl0aHJvdyBILmIoUC54WSgiQm90aCBxdWVyeSBhbmQgcXVlcnlQYXJhbWV0ZXJz
-IHNwZWNpZmllZCIpKQpyZXR1cm4gUC5QSShhLGIsYyxDLlZDLCEwKX1pZihkPT1udWxsKXJldHVybiBu
-dWxsCnQ9bmV3IFAuUm4oIiIpCnMuYT0iIgpkLksoMCxuZXcgUC55NShuZXcgUC5NRShzLHQpKSkKcz10
-LmEKcmV0dXJuIHMuY2hhckNvZGVBdCgwKT09MD9zOnN9LAp0RzpmdW5jdGlvbihhLGIsYyl7aWYoYT09
-bnVsbClyZXR1cm4gbnVsbApyZXR1cm4gUC5QSShhLGIsYyxDLlZDLCEwKX0sCnJ2OmZ1bmN0aW9uKGEs
-YixjKXt2YXIgdCxzLHIscSxwLG89YisyCmlmKG8+PWEubGVuZ3RoKXJldHVybiIlIgp0PUMueEIubShh
-LGIrMSkKcz1DLnhCLm0oYSxvKQpyPUgub28odCkKcT1ILm9vKHMpCmlmKHI8MHx8cTwwKXJldHVybiIl
-IgpwPXIqMTYrcQppZihwPDEyNyl7bz1DLmpuLndHKHAsNCkKaWYobz49OClyZXR1cm4gSC5rKEMuRjMs
-bykKbz0oQy5GM1tvXSYxPDwocCYxNSkpIT09MH1lbHNlIG89ITEKaWYobylyZXR1cm4gSC5MdyhjJiY2
-NTw9cCYmOTA+PXA/KHB8MzIpPj4+MDpwKQppZih0Pj05N3x8cz49OTcpcmV0dXJuIEMueEIuTmooYSxi
-LGIrMykudG9VcHBlckNhc2UoKQpyZXR1cm4gbnVsbH0sCnpYOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixx
-LHAsbyxuLG0sbD0iMDEyMzQ1Njc4OUFCQ0RFRiIKaWYoYTwxMjgpe3Q9bmV3IFVpbnQ4QXJyYXkoMykK
-cz10Lmxlbmd0aAppZigwPj1zKXJldHVybiBILmsodCwwKQp0WzBdPTM3CnI9Qy54Qi5XKGwsYT4+PjQp
-CmlmKDE+PXMpcmV0dXJuIEguayh0LDEpCnRbMV09cgpyPUMueEIuVyhsLGEmMTUpCmlmKDI+PXMpcmV0
-dXJuIEguayh0LDIpCnRbMl09cn1lbHNle2lmKGE+MjA0NylpZihhPjY1NTM1KXtxPTI0MApwPTR9ZWxz
-ZXtxPTIyNApwPTN9ZWxzZXtxPTE5MgpwPTJ9dD1uZXcgVWludDhBcnJheSgzKnApCmZvcihzPXQubGVu
-Z3RoLG89MDstLXAscD49MDtxPTEyOCl7bj1DLmpuLmJmKGEsNipwKSY2M3xxCmlmKG8+PXMpcmV0dXJu
-IEguayh0LG8pCnRbb109MzcKcj1vKzEKbT1DLnhCLlcobCxuPj4+NCkKaWYocj49cylyZXR1cm4gSC5r
-KHQscikKdFtyXT1tCm09bysyCnI9Qy54Qi5XKGwsbiYxNSkKaWYobT49cylyZXR1cm4gSC5rKHQsbSkK
-dFttXT1yCm8rPTN9fXJldHVybiBQLkhNKHQsMCxudWxsKX0sClBJOmZ1bmN0aW9uKGEsYixjLGQsZSl7
-dmFyIHQ9UC5VbChhLGIsYyxkLGUpCnJldHVybiB0PT1udWxsP0MueEIuTmooYSxiLGMpOnR9LApVbDpm
-dW5jdGlvbihhLGIsYyxkLGUpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrPW51bGwKZm9yKHQ9IWUscz1i
-LHI9cyxxPWs7czxjOyl7cD1DLnhCLm0oYSxzKQppZihwPDEyNyl7bz1wPj4+NAppZihvPj04KXJldHVy
-biBILmsoZCxvKQpvPShkW29dJjE8PChwJjE1KSkhPT0wfWVsc2Ugbz0hMQppZihvKSsrcwplbHNle2lm
-KHA9PT0zNyl7bj1QLnJ2KGEscywhMSkKaWYobj09bnVsbCl7cys9Mwpjb250aW51ZX1pZigiJSI9PT1u
-KXtuPSIlMjUiCm09MX1lbHNlIG09M31lbHNle2lmKHQpaWYocDw9OTMpe289cD4+PjQKaWYobz49OCly
-ZXR1cm4gSC5rKEMuYWssbykKbz0oQy5ha1tvXSYxPDwocCYxNSkpIT09MH1lbHNlIG89ITEKZWxzZSBv
-PSExCmlmKG8pe1AuUjMoYSxzLCJJbnZhbGlkIGNoYXJhY3RlciIpCm09awpuPW19ZWxzZXtpZigocCY2
-NDUxMik9PT01NTI5Nil7bz1zKzEKaWYobzxjKXtsPUMueEIubShhLG8pCmlmKChsJjY0NTEyKT09PTU2
-MzIwKXtwPTY1NTM2fChwJjEwMjMpPDwxMHxsJjEwMjMKbT0yfWVsc2UgbT0xfWVsc2UgbT0xfWVsc2Ug
-bT0xCm49UC56WChwKX19aWYocT09bnVsbCl7cT1uZXcgUC5SbigiIikKbz1xfWVsc2Ugbz1xCm8uYSs9
-Qy54Qi5OaihhLHIscykKby5hKz1ILmQobikKaWYodHlwZW9mIG0hPT0ibnVtYmVyIilyZXR1cm4gSC5w
-WShtKQpzKz1tCnI9c319aWYocT09bnVsbClyZXR1cm4gawppZihyPGMpcS5hKz1DLnhCLk5qKGEscixj
-KQp0PXEuYQpyZXR1cm4gdC5jaGFyQ29kZUF0KDApPT0wP3Q6dH0sCnlCOmZ1bmN0aW9uKGEpe2lmKEMu
-eEIubihhLCIuIikpcmV0dXJuITAKcmV0dXJuIEMueEIuT1koYSwiLy4iKSE9PS0xfSwKeGU6ZnVuY3Rp
-b24oYSl7dmFyIHQscyxyLHEscCxvLG4KaWYoIVAueUIoYSkpcmV0dXJuIGEKdD1ILlZNKFtdLHUucykK
-Zm9yKHM9YS5zcGxpdCgiLyIpLHI9cy5sZW5ndGgscT0hMSxwPTA7cDxyOysrcCl7bz1zW3BdCmlmKEou
-Uk0obywiLi4iKSl7bj10Lmxlbmd0aAppZihuIT09MCl7aWYoMD49bilyZXR1cm4gSC5rKHQsLTEpCnQu
-cG9wKCkKaWYodC5sZW5ndGg9PT0wKUMuTm0uaSh0LCIiKX1xPSEwfWVsc2UgaWYoIi4iPT09bylxPSEw
-CmVsc2V7Qy5ObS5pKHQsbykKcT0hMX19aWYocSlDLk5tLmkodCwiIikKcmV0dXJuIEMuTm0uelYodCwi
-LyIpfSwKd0Y6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG8KaWYoIVAueUIoYSkpcmV0dXJuIWI/
-UC5DMShhKTphCnQ9SC5WTShbXSx1LnMpCmZvcihzPWEuc3BsaXQoIi8iKSxyPXMubGVuZ3RoLHE9ITEs
-cD0wO3A8cjsrK3Ape289c1twXQppZigiLi4iPT09bylpZih0Lmxlbmd0aCE9PTAmJkMuTm0uZ3JaKHQp
-IT09Ii4uIil7aWYoMD49dC5sZW5ndGgpcmV0dXJuIEguayh0LC0xKQp0LnBvcCgpCnE9ITB9ZWxzZXtD
-Lk5tLmkodCwiLi4iKQpxPSExfWVsc2UgaWYoIi4iPT09bylxPSEwCmVsc2V7Qy5ObS5pKHQsbykKcT0h
-MX19cz10Lmxlbmd0aAppZihzIT09MClpZihzPT09MSl7aWYoMD49cylyZXR1cm4gSC5rKHQsMCkKcz10
-WzBdLmxlbmd0aD09PTB9ZWxzZSBzPSExCmVsc2Ugcz0hMAppZihzKXJldHVybiIuLyIKaWYocXx8Qy5O
-bS5ncloodCk9PT0iLi4iKUMuTm0uaSh0LCIiKQppZighYil7aWYoMD49dC5sZW5ndGgpcmV0dXJuIEgu
-ayh0LDApCkMuTm0uWSh0LDAsUC5DMSh0WzBdKSl9cmV0dXJuIEMuTm0uelYodCwiLyIpfSwKQzE6ZnVu
-Y3Rpb24oYSl7dmFyIHQscyxyLHE9YS5sZW5ndGgKaWYocT49MiYmUC5FdChKLlF6KGEsMCkpKWZvcih0
-PTE7dDxxOysrdCl7cz1DLnhCLlcoYSx0KQppZihzPT09NTgpcmV0dXJuIEMueEIuTmooYSwwLHQpKyIl
-M0EiK0MueEIuRyhhLHQrMSkKaWYoczw9MTI3KXtyPXM+Pj40CmlmKHI+PTgpcmV0dXJuIEguayhDLm1L
-LHIpCnI9KEMubUtbcl0mMTw8KHMmMTUpKT09PTB9ZWxzZSByPSEwCmlmKHIpYnJlYWt9cmV0dXJuIGF9
-LAptbjpmdW5jdGlvbihhKXt2YXIgdCxzLHIscT1hLmdGaigpLHA9cS5sZW5ndGgKaWYocD4wJiZKLkgo
-cVswXSk9PT0yJiZKLmE2KHFbMF0sMSk9PT01OCl7aWYoMD49cClyZXR1cm4gSC5rKHEsMCkKUC5yZyhK
-LmE2KHFbMF0sMCksITEpClAuSE4ocSwhMSwxKQp0PSEwfWVsc2V7UC5ITihxLCExLDApCnQ9ITF9cz1h
-Lmd0VCgpJiYhdD8iXFwiOiIiCmlmKGEuZ2NqKCkpe3I9YS5nSmYoYSkKaWYoci5sZW5ndGghPT0wKXM9
-cysiXFwiK3IrIlxcIn1zPVAudmcocyxxLCJcXCIpCnA9dCYmcD09PTE/cysiXFwiOnMKcmV0dXJuIHAu
-Y2hhckNvZGVBdCgwKT09MD9wOnB9LApJaDpmdW5jdGlvbihhLGIpe3ZhciB0LHMscgpmb3IodD0wLHM9
-MDtzPDI7KytzKXtyPUMueEIuVyhhLGIrcykKaWYoNDg8PXImJnI8PTU3KXQ9dCoxNityLTQ4CmVsc2V7
-cnw9MzIKaWYoOTc8PXImJnI8PTEwMil0PXQqMTYrci04NwplbHNlIHRocm93IEguYihQLnhZKCJJbnZh
-bGlkIFVSTCBlbmNvZGluZyIpKX19cmV0dXJuIHR9LAprdTpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciB0
-LHMscixxLHA9Si5yWShhKSxvPWIKd2hpbGUoITApe2lmKCEobzxjKSl7dD0hMApicmVha31zPXAuVyhh
-LG8pCmlmKHM8PTEyNylpZihzIT09Mzcpcj1lJiZzPT09NDMKZWxzZSByPSEwCmVsc2Ugcj0hMAppZihy
-KXt0PSExCmJyZWFrfSsrb31pZih0KXtpZihDLnhNIT09ZClyPSExCmVsc2Ugcj0hMAppZihyKXJldHVy
-biBwLk5qKGEsYixjKQplbHNlIHE9bmV3IEgucWoocC5OaihhLGIsYykpfWVsc2V7cT1ILlZNKFtdLHUu
-dCkKZm9yKG89YjtvPGM7KytvKXtzPXAuVyhhLG8pCmlmKHM+MTI3KXRocm93IEguYihQLnhZKCJJbGxl
-Z2FsIHBlcmNlbnQgZW5jb2RpbmcgaW4gVVJJIikpCmlmKHM9PT0zNyl7aWYobyszPmEubGVuZ3RoKXRo
-cm93IEguYihQLnhZKCJUcnVuY2F0ZWQgVVJJIikpCkMuTm0uaShxLFAuSWgoYSxvKzEpKQpvKz0yfWVs
-c2UgaWYoZSYmcz09PTQzKUMuTm0uaShxLDMyKQplbHNlIEMuTm0uaShxLHMpfX11LkwuYShxKQpyZXR1
-cm4gbmV3IFAuR1koITEpLldKKHEpfSwKRXQ6ZnVuY3Rpb24oYSl7dmFyIHQ9YXwzMgpyZXR1cm4gOTc8
-PXQmJnQ8PTEyMn0sCktEOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscSxwLG8sbixtLGw9IkludmFs
-aWQgTUlNRSB0eXBlIixrPUguVk0oW2ItMV0sdS50KQpmb3IodD1hLmxlbmd0aCxzPWIscj0tMSxxPW51
-bGw7czx0Oysrcyl7cT1DLnhCLlcoYSxzKQppZihxPT09NDR8fHE9PT01OSlicmVhawppZihxPT09NDcp
-e2lmKHI8MCl7cj1zCmNvbnRpbnVlfXRocm93IEguYihQLnJyKGwsYSxzKSl9fWlmKHI8MCYmcz5iKXRo
-cm93IEguYihQLnJyKGwsYSxzKSkKZm9yKDtxIT09NDQ7KXtDLk5tLmkoayxzKTsrK3MKZm9yKHA9LTE7
-czx0Oysrcyl7cT1DLnhCLlcoYSxzKQppZihxPT09NjEpe2lmKHA8MClwPXN9ZWxzZSBpZihxPT09NTl8
-fHE9PT00NClicmVha31pZihwPj0wKUMuTm0uaShrLHApCmVsc2V7bz1DLk5tLmdyWihrKQppZihxIT09
-NDR8fHMhPT1vKzd8fCFDLnhCLlFpKGEsImJhc2U2NCIsbysxKSl0aHJvdyBILmIoUC5ycigiRXhwZWN0
-aW5nICc9JyIsYSxzKSkKYnJlYWt9fUMuTm0uaShrLHMpCm49cysxCmlmKChrLmxlbmd0aCYxKT09PTEp
-YT1DLmg5LnlyKGEsbix0KQplbHNle209UC5VbChhLG4sdCxDLlZDLCEwKQppZihtIT1udWxsKWE9Qy54
-Qi5pNyhhLG4sdCxtKX1yZXR1cm4gbmV3IFAuUEUoYSxrLGMpfSwKS046ZnVuY3Rpb24oKXt2YXIgdD0i
-MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4
-eXotLl9+ISQmJygpKissOz0iLHM9Ii4iLHI9IjoiLHE9Ii8iLHA9Ij8iLG89IiMiLG49dS5nYyxtPVAu
-ZEgoMjIsbmV3IFAucTMoKSwhMCxuKSxsPW5ldyBQLnlJKG0pLGs9bmV3IFAuYzYoKSxqPW5ldyBQLnFk
-KCksaT1uLmEobC4kMigwLDIyNSkpCmsuJDMoaSx0LDEpCmsuJDMoaSxzLDE0KQprLiQzKGksciwzNCkK
-ay4kMyhpLHEsMykKay4kMyhpLHAsMTcyKQprLiQzKGksbywyMDUpCmk9bi5hKGwuJDIoMTQsMjI1KSkK
-ay4kMyhpLHQsMSkKay4kMyhpLHMsMTUpCmsuJDMoaSxyLDM0KQprLiQzKGkscSwyMzQpCmsuJDMoaSxw
-LDE3MikKay4kMyhpLG8sMjA1KQppPW4uYShsLiQyKDE1LDIyNSkpCmsuJDMoaSx0LDEpCmsuJDMoaSwi
-JSIsMjI1KQprLiQzKGksciwzNCkKay4kMyhpLHEsOSkKay4kMyhpLHAsMTcyKQprLiQzKGksbywyMDUp
-Cmk9bi5hKGwuJDIoMSwyMjUpKQprLiQzKGksdCwxKQprLiQzKGksciwzNCkKay4kMyhpLHEsMTApCmsu
-JDMoaSxwLDE3MikKay4kMyhpLG8sMjA1KQppPW4uYShsLiQyKDIsMjM1KSkKay4kMyhpLHQsMTM5KQpr
-LiQzKGkscSwxMzEpCmsuJDMoaSxzLDE0NikKay4kMyhpLHAsMTcyKQprLiQzKGksbywyMDUpCmk9bi5h
-KGwuJDIoMywyMzUpKQprLiQzKGksdCwxMSkKay4kMyhpLHEsNjgpCmsuJDMoaSxzLDE4KQprLiQzKGks
-cCwxNzIpCmsuJDMoaSxvLDIwNSkKaT1uLmEobC4kMig0LDIyOSkpCmsuJDMoaSx0LDUpCmouJDMoaSwi
-QVoiLDIyOSkKay4kMyhpLHIsMTAyKQprLiQzKGksIkAiLDY4KQprLiQzKGksIlsiLDIzMikKay4kMyhp
-LHEsMTM4KQprLiQzKGkscCwxNzIpCmsuJDMoaSxvLDIwNSkKaT1uLmEobC4kMig1LDIyOSkpCmsuJDMo
-aSx0LDUpCmouJDMoaSwiQVoiLDIyOSkKay4kMyhpLHIsMTAyKQprLiQzKGksIkAiLDY4KQprLiQzKGks
-cSwxMzgpCmsuJDMoaSxwLDE3MikKay4kMyhpLG8sMjA1KQppPW4uYShsLiQyKDYsMjMxKSkKai4kMyhp
-LCIxOSIsNykKay4kMyhpLCJAIiw2OCkKay4kMyhpLHEsMTM4KQprLiQzKGkscCwxNzIpCmsuJDMoaSxv
-LDIwNSkKaT1uLmEobC4kMig3LDIzMSkpCmouJDMoaSwiMDkiLDcpCmsuJDMoaSwiQCIsNjgpCmsuJDMo
-aSxxLDEzOCkKay4kMyhpLHAsMTcyKQprLiQzKGksbywyMDUpCmsuJDMobi5hKGwuJDIoOCw4KSksIl0i
-LDUpCmk9bi5hKGwuJDIoOSwyMzUpKQprLiQzKGksdCwxMSkKay4kMyhpLHMsMTYpCmsuJDMoaSxxLDIz
-NCkKay4kMyhpLHAsMTcyKQprLiQzKGksbywyMDUpCmk9bi5hKGwuJDIoMTYsMjM1KSkKay4kMyhpLHQs
-MTEpCmsuJDMoaSxzLDE3KQprLiQzKGkscSwyMzQpCmsuJDMoaSxwLDE3MikKay4kMyhpLG8sMjA1KQpp
-PW4uYShsLiQyKDE3LDIzNSkpCmsuJDMoaSx0LDExKQprLiQzKGkscSw5KQprLiQzKGkscCwxNzIpCmsu
-JDMoaSxvLDIwNSkKaT1uLmEobC4kMigxMCwyMzUpKQprLiQzKGksdCwxMSkKay4kMyhpLHMsMTgpCmsu
-JDMoaSxxLDIzNCkKay4kMyhpLHAsMTcyKQprLiQzKGksbywyMDUpCmk9bi5hKGwuJDIoMTgsMjM1KSkK
-ay4kMyhpLHQsMTEpCmsuJDMoaSxzLDE5KQprLiQzKGkscSwyMzQpCmsuJDMoaSxwLDE3MikKay4kMyhp
-LG8sMjA1KQppPW4uYShsLiQyKDE5LDIzNSkpCmsuJDMoaSx0LDExKQprLiQzKGkscSwyMzQpCmsuJDMo
-aSxwLDE3MikKay4kMyhpLG8sMjA1KQppPW4uYShsLiQyKDExLDIzNSkpCmsuJDMoaSx0LDExKQprLiQz
-KGkscSwxMCkKay4kMyhpLHAsMTcyKQprLiQzKGksbywyMDUpCmk9bi5hKGwuJDIoMTIsMjM2KSkKay4k
-MyhpLHQsMTIpCmsuJDMoaSxwLDEyKQprLiQzKGksbywyMDUpCmk9bi5hKGwuJDIoMTMsMjM3KSkKay4k
-MyhpLHQsMTMpCmsuJDMoaSxwLDEzKQpqLiQzKG4uYShsLiQyKDIwLDI0NSkpLCJheiIsMjEpCmw9bi5h
-KGwuJDIoMjEsMjQ1KSkKai4kMyhsLCJheiIsMjEpCmouJDMobCwiMDkiLDIxKQprLiQzKGwsIistLiIs
-MjEpCnJldHVybiBtfSwKVUI6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgdCxzLHIscSxwLG89JC52Wigp
-CmZvcih0PUouclkoYSkscz1iO3M8YzsrK3Mpe2lmKGQ8MHx8ZD49by5sZW5ndGgpcmV0dXJuIEguayhv
-LGQpCnI9b1tkXQpxPXQuVyhhLHMpXjk2CmlmKHE+OTUpcT0zMQppZihxPj1yLmxlbmd0aClyZXR1cm4g
-SC5rKHIscSkKcD1yW3FdCmQ9cCYzMQpDLk5tLlkoZSxwPj4+NSxzKX1yZXR1cm4gZH0sCldGOmZ1bmN0
-aW9uIFdGKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAphMjpmdW5jdGlvbiBhMigpe30sCmlQOmZ1bmN0
-aW9uIGlQKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApDUDpmdW5jdGlvbiBDUCgpe30sClhTOmZ1bmN0
-aW9uIFhTKCl7fSwKQzY6ZnVuY3Rpb24gQzYoYSl7dGhpcy5hPWF9LApMSzpmdW5jdGlvbiBMSygpe30s
-CkFUOmZ1bmN0aW9uIEFUKGEsYixjLGQpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWR9
-LApiSjpmdW5jdGlvbiBiSihhLGIsYyxkLGUsZil7dmFyIF89dGhpcwpfLmU9YQpfLmY9YgpfLmE9Ywpf
-LmI9ZApfLmM9ZQpfLmQ9Zn0sCmVZOmZ1bmN0aW9uIGVZKGEsYixjLGQsZSl7dmFyIF89dGhpcwpfLmY9
-YQpfLmE9YgpfLmI9YwpfLmM9ZApfLmQ9ZX0sCm1wOmZ1bmN0aW9uIG1wKGEsYixjLGQpe3ZhciBfPXRo
-aXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWR9LAp1YjpmdW5jdGlvbiB1YihhKXt0aGlzLmE9YX0sCmRz
-OmZ1bmN0aW9uIGRzKGEpe3RoaXMuYT1hfSwKbGo6ZnVuY3Rpb24gbGooYSl7dGhpcy5hPWF9LApVVjpm
-dW5jdGlvbiBVVihhKXt0aGlzLmE9YX0sCms1OmZ1bmN0aW9uIGs1KCl7fSwKS1k6ZnVuY3Rpb24gS1ko
-KXt9LAp0NzpmdW5jdGlvbiB0NyhhKXt0aGlzLmE9YX0sCkNEOmZ1bmN0aW9uIENEKGEpe3RoaXMuYT1h
-fSwKYUU6ZnVuY3Rpb24gYUUoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKRUg6ZnVu
-Y3Rpb24gRUgoKXt9LApJZjpmdW5jdGlvbiBJZigpe30sCmNYOmZ1bmN0aW9uIGNYKCl7fSwKQW46ZnVu
-Y3Rpb24gQW4oKXt9LAp6TTpmdW5jdGlvbiB6TSgpe30sClowOmZ1bmN0aW9uIFowKCl7fSwKTjM6ZnVu
-Y3Rpb24gTjMoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuJHRpPWN9LApjODpmdW5jdGlvbiBj
-OCgpe30sCmxmOmZ1bmN0aW9uIGxmKCl7fSwKTWg6ZnVuY3Rpb24gTWgoKXt9LApPZDpmdW5jdGlvbiBP
-ZCgpe30sCmliOmZ1bmN0aW9uIGliKCl7fSwKeHU6ZnVuY3Rpb24geHUoKXt9LApHejpmdW5jdGlvbiBH
-eigpe30sClpkOmZ1bmN0aW9uIFpkKCl7fSwKcVU6ZnVuY3Rpb24gcVUoKXt9LApSbjpmdW5jdGlvbiBS
-bihhKXt0aGlzLmE9YX0sCkdEOmZ1bmN0aW9uIEdEKCl7fSwKbjE6ZnVuY3Rpb24gbjEoYSl7dGhpcy5h
-PWF9LApjUzpmdW5jdGlvbiBjUyhhKXt0aGlzLmE9YX0sClZDOmZ1bmN0aW9uIFZDKGEpe3RoaXMuYT1h
-fSwKSlQ6ZnVuY3Rpb24gSlQoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCkRuOmZ1bmN0aW9uIERuKGEs
-YixjLGQsZSxmLGcpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWQKXy5lPWUKXy5mPWYK
-Xy5yPWcKXy5RPV8uej1fLnk9Xy54PW51bGx9LApSWjpmdW5jdGlvbiBSWigpe30sCk1FOmZ1bmN0aW9u
-IE1FKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAp5NTpmdW5jdGlvbiB5NShhKXt0aGlzLmE9YX0sClBF
-OmZ1bmN0aW9uIFBFKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCnEzOmZ1bmN0aW9u
-IHEzKCl7fSwKeUk6ZnVuY3Rpb24geUkoYSl7dGhpcy5hPWF9LApjNjpmdW5jdGlvbiBjNigpe30sCnFk
-OmZ1bmN0aW9uIHFkKCl7fSwKVWY6ZnVuY3Rpb24gVWYoYSxiLGMsZCxlLGYsZyxoKXt2YXIgXz10aGlz
-Cl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kCl8uZT1lCl8uZj1mCl8ucj1nCl8ueD1oCl8ueT1udWxsfSwK
-cWU6ZnVuY3Rpb24gcWUoYSxiLGMsZCxlLGYsZyl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9Ywpf
-LmQ9ZApfLmU9ZQpfLmY9ZgpfLnI9ZwpfLlE9Xy56PV8ueT1fLng9bnVsbH0sCmlKOmZ1bmN0aW9uIGlK
-KCl7fSwKamc6ZnVuY3Rpb24gamcoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sClRhOmZ1bmN0aW9uIFRh
-KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApCZjpmdW5jdGlvbiBCZihhLGIpe3RoaXMuYT1hCnRoaXMu
-Yj1ifSwKQXM6ZnVuY3Rpb24gQXMoKXt9LApHRTpmdW5jdGlvbiBHRShhKXt0aGlzLmE9YX0sCk43OmZ1
-bmN0aW9uIE43KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAp1UTpmdW5jdGlvbiB1USgpe30sCmhGOmZ1
-bmN0aW9uIGhGKCl7fSwKUjQ6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyCkguRTkoYikKdS5qLmEo
-ZCkKaWYoSC5vVChiKSl7dD1bY10KQy5ObS5GVih0LGQpCmQ9dH1zPXUuegpyPVAuQ0goSi5NMShkLFAu
-dzAoKSxzKSwhMCxzKQp1LlouYShhKQpyZXR1cm4gUC53WShILkVrKGEscixudWxsKSl9LApEbTpmdW5j
-dGlvbihhLGIsYyl7dmFyIHQKdHJ5e2lmKE9iamVjdC5pc0V4dGVuc2libGUoYSkmJiFPYmplY3QucHJv
-dG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYSxiKSl7T2JqZWN0LmRlZmluZVByb3BlcnR5KGEsYix7
-dmFsdWU6Y30pCnJldHVybiEwfX1jYXRjaCh0KXtILlJ1KHQpfXJldHVybiExfSwKT206ZnVuY3Rpb24o
-YSxiKXtpZihPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYSxiKSlyZXR1cm4gYVti
-XQpyZXR1cm4gbnVsbH0sCndZOmZ1bmN0aW9uKGEpe2lmKGE9PW51bGx8fHR5cGVvZiBhPT0ic3RyaW5n
-Inx8dHlwZW9mIGE9PSJudW1iZXIifHxILnJRKGEpKXJldHVybiBhCmlmKGEgaW5zdGFuY2VvZiBQLkU0
-KXJldHVybiBhLmEKaWYoSC5SOShhKSlyZXR1cm4gYQppZih1LncuYihhKSlyZXR1cm4gYQppZihhIGlu
-c3RhbmNlb2YgUC5pUClyZXR1cm4gSC5vMihhKQppZih1LlouYihhKSlyZXR1cm4gUC5oRShhLCIkZGFy
-dF9qc0Z1bmN0aW9uIixuZXcgUC5QQygpKQpyZXR1cm4gUC5oRShhLCJfJGRhcnRfanNPYmplY3QiLG5l
-dyBQLm10KCQua0koKSkpfSwKaEU6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PVAuT20oYSxiKQppZih0PT1u
-dWxsKXt0PWMuJDEoYSkKUC5EbShhLGIsdCl9cmV0dXJuIHR9LApMNzpmdW5jdGlvbihhKXt2YXIgdCxz
-CmlmKGE9PW51bGx8fHR5cGVvZiBhPT0ic3RyaW5nInx8dHlwZW9mIGE9PSJudW1iZXIifHx0eXBlb2Yg
-YT09ImJvb2xlYW4iKXJldHVybiBhCmVsc2UgaWYoYSBpbnN0YW5jZW9mIE9iamVjdCYmSC5SOShhKSly
-ZXR1cm4gYQplbHNlIGlmKGEgaW5zdGFuY2VvZiBPYmplY3QmJnUudy5iKGEpKXJldHVybiBhCmVsc2Ug
-aWYoYSBpbnN0YW5jZW9mIERhdGUpe3Q9SC5XWShhLmdldFRpbWUoKSkKaWYoTWF0aC5hYnModCk8PTg2
-NGUxMylzPSExCmVsc2Ugcz0hMAppZihzKUgudmgoUC54WSgiRGF0ZVRpbWUgaXMgb3V0c2lkZSB2YWxp
-ZCByYW5nZTogIit0KSkKUC5VSSghMSwiaXNVdGMiLHUueSkKcmV0dXJuIG5ldyBQLmlQKHQsITEpfWVs
-c2UgaWYoYS5jb25zdHJ1Y3Rvcj09PSQua0koKSlyZXR1cm4gYS5vCmVsc2UgcmV0dXJuIFAuTkQoYSl9
-LApORDpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09ImZ1bmN0aW9uIilyZXR1cm4gUC5pUShhLCQud1Eo
-KSxuZXcgUC5OeigpKQppZihhIGluc3RhbmNlb2YgQXJyYXkpcmV0dXJuIFAuaVEoYSwkLkNyKCksbmV3
-IFAuUVMoKSkKcmV0dXJuIFAuaVEoYSwkLkNyKCksbmV3IFAubnAoKSl9LAppUTpmdW5jdGlvbihhLGIs
-Yyl7dmFyIHQ9UC5PbShhLGIpCmlmKHQ9PW51bGx8fCEoYSBpbnN0YW5jZW9mIE9iamVjdCkpe3Q9Yy4k
-MShhKQpQLkRtKGEsYix0KX1yZXR1cm4gdH0sClBDOmZ1bmN0aW9uIFBDKCl7fSwKbXQ6ZnVuY3Rpb24g
-bXQoYSl7dGhpcy5hPWF9LApOejpmdW5jdGlvbiBOeigpe30sClFTOmZ1bmN0aW9uIFFTKCl7fSwKbnA6
-ZnVuY3Rpb24gbnAoKXt9LApFNDpmdW5jdGlvbiBFNChhKXt0aGlzLmE9YX0sCnI3OmZ1bmN0aW9uIHI3
-KGEpe3RoaXMuYT1hfSwKVHo6ZnVuY3Rpb24gVHooYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKY286
-ZnVuY3Rpb24gY28oKXt9LApiQjpmdW5jdGlvbiBiQigpe30sCktlOmZ1bmN0aW9uIEtlKGEpe3RoaXMu
-YT1hfSwKZDU6ZnVuY3Rpb24gZDUoKXt9LApuNjpmdW5jdGlvbiBuNigpe319LFc9ewp4MzpmdW5jdGlv
-bigpe3JldHVybiB3aW5kb3d9LApacjpmdW5jdGlvbigpe3JldHVybiBkb2N1bWVudH0sCko2OmZ1bmN0
-aW9uKCl7dmFyIHQ9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiYSIpCnJldHVybiB0fSwKVTk6ZnVuY3Rp
-b24oYSxiLGMpe3ZhciB0LHM9ZG9jdW1lbnQuYm9keQpzLnRvU3RyaW5nCnQ9Qy5SWS5yNihzLGEsYixj
-KQp0LnRvU3RyaW5nCnM9dS5hYwpzPW5ldyBILlU1KG5ldyBXLmU3KHQpLHMuQygiYTIobEQuRSkiKS5h
-KG5ldyBXLkN2KCkpLHMuQygiVTU8bEQuRT4iKSkKcmV0dXJuIHUuaC5hKHMuZ3I4KHMpKX0sCnJTOmZ1
-bmN0aW9uKGEpe3ZhciB0LHMscj0iZWxlbWVudCB0YWcgdW5hdmFpbGFibGUiCnRyeXt0PUouUkUoYSkK
-aWYodHlwZW9mIHQuZ25zKGEpPT0ic3RyaW5nIilyPXQuZ25zKGEpfWNhdGNoKHMpe0guUnUocyl9cmV0
-dXJuIHJ9LApxRDpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxPW5ldyBQLnZzKCQuWDMsdS5ZKSxwPW5l
-dyBQLlpmKHEsdS5FKSxvPW5ldyBYTUxIdHRwUmVxdWVzdCgpCkMuRHQuZW8obywiR0VUIixhLCEwKQpi
-LksoMCxuZXcgVy5iVShvKSkKdD11LmFuCnM9dC5hKG5ldyBXLmhIKG8scCkpCnUuTS5hKG51bGwpCnI9
-dS5wClcuSkUobywibG9hZCIscywhMSxyKQpXLkpFKG8sImVycm9yIix0LmEocC5nWUooKSksITEscikK
-by5zZW5kKCkKcmV0dXJuIHF9LApDMDpmdW5jdGlvbihhLGIpe2E9NTM2ODcwOTExJmErYgphPTUzNjg3
-MDkxMSZhKygoNTI0Mjg3JmEpPDwxMCkKcmV0dXJuIGFeYT4+PjZ9LApyRTpmdW5jdGlvbihhLGIsYyxk
-KXt2YXIgdD1XLkMwKFcuQzAoVy5DMChXLkMwKDAsYSksYiksYyksZCkscz01MzY4NzA5MTEmdCsoKDY3
-MTA4ODYzJnQpPDwzKQpzXj1zPj4+MTEKcmV0dXJuIDUzNjg3MDkxMSZzKygoMTYzODMmcyk8PDE1KX0s
-ClROOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyPWEuY2xhc3NMaXN0CmZvcih0PWIubGVuZ3RoLHM9MDtz
-PGIubGVuZ3RoO2IubGVuZ3RoPT09dHx8KDAsSC5saykoYiksKytzKXIuYWRkKGJbc10pfSwKSkU6ZnVu
-Y3Rpb24oYSxiLGMsZCxlKXt2YXIgdD1XLmFGKG5ldyBXLnZOKGMpLHUuQikKaWYodCE9bnVsbCYmITAp
-Si5kWihhLGIsdCwhMSkKcmV0dXJuIG5ldyBXLnhDKGEsYix0LCExLGUuQygieEM8MD4iKSl9LApUdzpm
-dW5jdGlvbihhKXt2YXIgdD1XLko2KCkscz13aW5kb3cubG9jYXRpb24KdD1uZXcgVy5KUShuZXcgVy5t
-ayh0LHMpKQp0LkNZKGEpCnJldHVybiB0fSwKeVc6ZnVuY3Rpb24oYSxiLGMsZCl7dS5oLmEoYSkKSC5j
-KGIpCkguYyhjKQp1LmNyLmEoZCkKcmV0dXJuITB9LApRVzpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxz
-LHIKdS5oLmEoYSkKSC5jKGIpCkguYyhjKQp0PXUuY3IuYShkKS5hCnM9dC5hCnMuaHJlZj1jCnI9cy5o
-b3N0bmFtZQp0PXQuYgppZighKHI9PXQuaG9zdG5hbWUmJnMucG9ydD09dC5wb3J0JiZzLnByb3RvY29s
-PT10LnByb3RvY29sKSlpZihyPT09IiIpaWYocy5wb3J0PT09IiIpe3Q9cy5wcm90b2NvbAp0PXQ9PT0i
-OiJ8fHQ9PT0iIn1lbHNlIHQ9ITEKZWxzZSB0PSExCmVsc2UgdD0hMApyZXR1cm4gdH0sCkJsOmZ1bmN0
-aW9uKCl7dmFyIHQ9dS5OLHM9UC50TShDLlF4LHQpLHI9dS5kRy5hKG5ldyBXLklBKCkpLHE9SC5WTShb
-IlRFTVBMQVRFIl0sdS5zKQp0PW5ldyBXLmN0KHMsUC5Mcyh0KSxQLkxzKHQpLFAuTHModCksbnVsbCkK
-dC5DWShudWxsLG5ldyBILmxKKEMuUXgscix1LmR2KSxxLG51bGwpCnJldHVybiB0fSwKUHY6ZnVuY3Rp
-b24oYSl7aWYoYT09bnVsbClyZXR1cm4gbnVsbApyZXR1cm4gVy5QMShhKX0sCnFjOmZ1bmN0aW9uKGEp
-e3ZhciB0CmlmKGE9PW51bGwpcmV0dXJuIG51bGwKaWYoInBvc3RNZXNzYWdlIiBpbiBhKXt0PVcuUDEo
-YSkKaWYodS51LmIodCkpcmV0dXJuIHQKcmV0dXJuIG51bGx9ZWxzZSByZXR1cm4gdS51LmEoYSl9LApQ
-MTpmdW5jdGlvbihhKXtpZihhPT09d2luZG93KXJldHVybiB1LmNpLmEoYSkKZWxzZSByZXR1cm4gbmV3
-IFcuZFcoYSl9LApISDpmdW5jdGlvbihhKXtpZihhPT09d2luZG93LmxvY2F0aW9uKXJldHVybiBhCmVs
-c2UgcmV0dXJuIG5ldyBXLkZiKCl9LAphRjpmdW5jdGlvbihhLGIpe3ZhciB0PSQuWDMKaWYodD09PUMu
-TlUpcmV0dXJuIGEKcmV0dXJuIHQuUHkoYSxiKX0sCnFFOmZ1bmN0aW9uIHFFKCl7fSwKR2g6ZnVuY3Rp
-b24gR2goKXt9LApmWTpmdW5jdGlvbiBmWSgpe30sCm5COmZ1bmN0aW9uIG5CKCl7fSwKQXo6ZnVuY3Rp
-b24gQXooKXt9LApRUDpmdW5jdGlvbiBRUCgpe30sCm54OmZ1bmN0aW9uIG54KCl7fSwKb0o6ZnVuY3Rp
-b24gb0ooKXt9LAppZDpmdW5jdGlvbiBpZCgpe30sClFGOmZ1bmN0aW9uIFFGKCl7fSwKTmg6ZnVuY3Rp
-b24gTmgoKXt9LApJQjpmdW5jdGlvbiBJQigpe30sCm43OmZ1bmN0aW9uIG43KCl7fSwKd3o6ZnVuY3Rp
-b24gd3ooYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKY3Y6ZnVuY3Rpb24gY3YoKXt9LApDdjpmdW5j
-dGlvbiBDdigpe30sCmVhOmZ1bmN0aW9uIGVhKCl7fSwKRDA6ZnVuY3Rpb24gRDAoKXt9LApUNTpmdW5j
-dGlvbiBUNSgpe30sCmg0OmZ1bmN0aW9uIGg0KCl7fSwKYnI6ZnVuY3Rpb24gYnIoKXt9LApWYjpmdW5j
-dGlvbiBWYigpe30sCmZKOmZ1bmN0aW9uIGZKKCl7fSwKYlU6ZnVuY3Rpb24gYlUoYSl7dGhpcy5hPWF9
-LApoSDpmdW5jdGlvbiBoSChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKd2E6ZnVuY3Rpb24gd2EoKXt9
-LApTZzpmdW5jdGlvbiBTZygpe30sCnU4OmZ1bmN0aW9uIHU4KCl7fSwKT0s6ZnVuY3Rpb24gT0soKXt9
-LAplNzpmdW5jdGlvbiBlNyhhKXt0aGlzLmE9YX0sCnVIOmZ1bmN0aW9uIHVIKCl7fSwKQkg6ZnVuY3Rp
-b24gQkgoKXt9LApTTjpmdW5jdGlvbiBTTigpe30sCmV3OmZ1bmN0aW9uIGV3KCl7fSwKbHA6ZnVuY3Rp
-b24gbHAoKXt9LApUYjpmdW5jdGlvbiBUYigpe30sCkl2OmZ1bmN0aW9uIEl2KCl7fSwKV1A6ZnVuY3Rp
-b24gV1AoKXt9LAp5WTpmdW5jdGlvbiB5WSgpe30sCnc2OmZ1bmN0aW9uIHc2KCl7fSwKSzU6ZnVuY3Rp
-b24gSzUoKXt9LApDbTpmdW5jdGlvbiBDbSgpe30sCkNROmZ1bmN0aW9uIENRKCl7fSwKdzQ6ZnVuY3Rp
-b24gdzQoKXt9LApyaDpmdW5jdGlvbiByaCgpe30sCmNmOmZ1bmN0aW9uIGNmKCl7fSwKaTc6ZnVuY3Rp
-b24gaTcoYSl7dGhpcy5hPWF9LApTeTpmdW5jdGlvbiBTeShhKXt0aGlzLmE9YX0sCktTOmZ1bmN0aW9u
-IEtTKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApBMzpmdW5jdGlvbiBBMyhhLGIpe3RoaXMuYT1hCnRo
-aXMuYj1ifSwKSTQ6ZnVuY3Rpb24gSTQoYSl7dGhpcy5hPWF9LApGazpmdW5jdGlvbiBGayhhLGIpe3Ro
-aXMuYT1hCnRoaXMuJHRpPWJ9LApSTzpmdW5jdGlvbiBSTyhhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1h
-Cl8uYj1iCl8uYz1jCl8uJHRpPWR9LApldTpmdW5jdGlvbiBldShhLGIsYyxkKXt2YXIgXz10aGlzCl8u
-YT1hCl8uYj1iCl8uYz1jCl8uJHRpPWR9LAp4QzpmdW5jdGlvbiB4QyhhLGIsYyxkLGUpe3ZhciBfPXRo
-aXMKXy5iPWEKXy5jPWIKXy5kPWMKXy5lPWQKXy4kdGk9ZX0sCnZOOmZ1bmN0aW9uIHZOKGEpe3RoaXMu
-YT1hfSwKSlE6ZnVuY3Rpb24gSlEoYSl7dGhpcy5hPWF9LApHbTpmdW5jdGlvbiBHbSgpe30sCnZEOmZ1
-bmN0aW9uIHZEKGEpe3RoaXMuYT1hfSwKVXY6ZnVuY3Rpb24gVXYoYSl7dGhpcy5hPWF9LApFZzpmdW5j
-dGlvbiBFZyhhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LAptNjpmdW5jdGlvbiBtNigp
-e30sCkVvOmZ1bmN0aW9uIEVvKCl7fSwKV2s6ZnVuY3Rpb24gV2soKXt9LApjdDpmdW5jdGlvbiBjdChh
-LGIsYyxkLGUpe3ZhciBfPXRoaXMKXy5lPWEKXy5hPWIKXy5iPWMKXy5jPWQKXy5kPWV9LApJQTpmdW5j
-dGlvbiBJQSgpe30sCk93OmZ1bmN0aW9uIE93KCl7fSwKVzk6ZnVuY3Rpb24gVzkoYSxiLGMpe3ZhciBf
-PXRoaXMKXy5hPWEKXy5iPWIKXy5jPS0xCl8uZD1udWxsCl8uJHRpPWN9LApkVzpmdW5jdGlvbiBkVyhh
-KXt0aGlzLmE9YX0sCkZiOmZ1bmN0aW9uIEZiKCl7fSwKa0Y6ZnVuY3Rpb24ga0YoKXt9LAptazpmdW5j
-dGlvbiBtayhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKS286ZnVuY3Rpb24gS28oYSl7dGhpcy5hPWEK
-dGhpcy5iPSExfSwKZm06ZnVuY3Rpb24gZm0oYSl7dGhpcy5hPWF9LApMZTpmdW5jdGlvbiBMZSgpe30s
-Cks3OmZ1bmN0aW9uIEs3KCl7fSwKckI6ZnVuY3Rpb24gckIoKXt9LApYVzpmdW5jdGlvbiBYVygpe30s
-Cm9hOmZ1bmN0aW9uIG9hKCl7fX0sVT17CmpmOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxCmlmKGE9PW51
-bGwpdD1udWxsCmVsc2V7dD1ILlZNKFtdLHUuZkEpCmZvcihzPUouSVQodS5SLmEoYSkpO3MuRigpOyl7
-cj1zLmdsKCkKcT1KLlU2KHIpCkMuTm0uaSh0LG5ldyBVLlNlKEguYyhxLnEociwiZGVzY3JpcHRpb24i
-KSksSC5jKHEucShyLCJocmVmIikpKSl9fXJldHVybiB0fSwKTmQ6ZnVuY3Rpb24oYSl7dmFyIHQscwpp
-ZihhPT1udWxsKXQ9bnVsbAplbHNle3Q9SC5WTShbXSx1LmhoKQpmb3Iocz1KLklUKHUuUi5hKGEpKTtz
-LkYoKTspQy5ObS5pKHQsVS5KaihzLmdsKCkpKX1yZXR1cm4gdH0sCkpqOmZ1bmN0aW9uKGEpe3ZhciB0
-LHMscixxLHAsbz0iZGVzY3JpcHRpb24iLG49Si5VNihhKSxtPUguYyhuLnEoYSxvKSksbD1ILlZNKFtd
-LHUuYUopCmZvcihuPUouSVQodS5SLmEobi5xKGEsImVudHJpZXMiKSkpO24uRigpOyl7dD1uLmdsKCkK
-cz1KLlU2KHQpCnI9SC5jKHMucSh0LG8pKQpxPUguYyhzLnEodCwiZnVuY3Rpb24iKSkKcz1zLnEodCwi
-bGluayIpCmlmKHM9PW51bGwpcz1udWxsCmVsc2V7cD1KLlU2KHMpCnM9bmV3IFUuTWwoSC5jKHAucShz
-LCJocmVmIikpLEguV1kocC5xKHMsImxpbmUiKSksSC5jKHAucShzLCJwYXRoIikpKX1DLk5tLmkobCxu
-ZXcgVS53YihyLHEscykpfXJldHVybiBuZXcgVS55RChtLGwpfSwKZDI6ZnVuY3Rpb24gZDIoYSxiLGMs
-ZCxlKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kCl8uZT1lfSwKU2U6ZnVuY3Rpb24g
-U2UoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCk1sOmZ1bmN0aW9uIE1sKGEsYixjKXt0aGlzLmE9YQp0
-aGlzLmI9Ygp0aGlzLmM9Y30sCnlEOmZ1bmN0aW9uIHlEKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAp3
-YjpmdW5jdGlvbiB3YihhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9fSxCPXsKWWY6ZnVu
-Y3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG4sbSxsPUguYyhhLnEoMCwicmVnaW9ucyIpKSxrPUguYyhh
-LnEoMCwibmF2aWdhdGlvbkNvbnRlbnQiKSksaj1ILmMoYS5xKDAsInNvdXJjZUNvZGUiKSksaT1QLkZs
-KHUuTix1LmY0KQpmb3IodD11LlMuYShhLnEoMCwiZWRpdHMiKSksdD10LmdQdSh0KSx0PXQuZ2t6KHQp
-LHM9dS5SLHI9dS5naTt0LkYoKTspe3E9dC5nbCgpCnA9cS5hCm89SC5WTShbXSxyKQpmb3IocT1KLklU
-KHMuYShxLmIpKTtxLkYoKTspe249cS5nbCgpCm09Si5VNihuKQpDLk5tLmkobyxuZXcgQi5qOChILldZ
-KG0ucShuLCJsaW5lIikpLEguYyhtLnEobiwiZXhwbGFuYXRpb24iKSksSC5XWShtLnEobiwib2Zmc2V0
-IikpKSl9aS5ZKDAscCxvKX1yZXR1cm4gbmV3IEIucXAobCxrLGosaSl9LApqODpmdW5jdGlvbiBqOChh
-LGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApxcDpmdW5jdGlvbiBxcChhLGIsYyxkKXt2
-YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kfSwKZnY6ZnVuY3Rpb24gZnYoKXt9LApPUzpm
-dW5jdGlvbihhKXt2YXIgdAppZighKGE+PTY1JiZhPD05MCkpdD1hPj05NyYmYTw9MTIyCmVsc2UgdD0h
-MApyZXR1cm4gdH0sCll1OmZ1bmN0aW9uKGEsYil7dmFyIHQ9YS5sZW5ndGgscz1iKzIKaWYodDxzKXJl
-dHVybiExCmlmKCFCLk9TKEMueEIubShhLGIpKSlyZXR1cm4hMQppZihDLnhCLm0oYSxiKzEpIT09NTgp
-cmV0dXJuITEKaWYodD09PXMpcmV0dXJuITAKcmV0dXJuIEMueEIubShhLHMpPT09NDd9fSxUPXttUTpm
-dW5jdGlvbiBtUSgpe319LEw9ewpJcTpmdW5jdGlvbigpe0MuQlouQihkb2N1bWVudCwiRE9NQ29udGVu
-dExvYWRlZCIsbmV3IEwuZSgpKQpDLm9sLkIod2luZG93LCJwb3BzdGF0ZSIsbmV3IEwuTCgpKX0sCmt6
-OmZ1bmN0aW9uKGEpe3ZhciB0LHM9dS5oLmEoYS5wYXJlbnROb2RlKS5xdWVyeVNlbGVjdG9yKCI6c2Nv
-cGUgPiB1bCIpLHI9cy5zdHlsZSxxPSIiK0MuQ0QuelEocy5vZmZzZXRIZWlnaHQpKjIrInB4IgpyLm1h
-eEhlaWdodD1xCnI9Si5xRihhKQpxPXIuJHRpCnQ9cS5DKCJ+KDEpIikuYShuZXcgTC5XeChzLGEpKQp1
-Lk0uYShudWxsKQpXLkpFKHIuYSxyLmIsdCwhMSxxLmMpfSwKeVg6ZnVuY3Rpb24oYSxiKXt2YXIgdCxz
-LHIscSxwLG89InF1ZXJ5U2VsZWN0b3JBbGwiLG49ZG9jdW1lbnQucXVlcnlTZWxlY3RvcihhKSxtPXUu
-aApuLnRvU3RyaW5nCkguRGgobSxtLCJUIixvKQp0PXUuVApzPW5ldyBXLnd6KG4ucXVlcnlTZWxlY3Rv
-ckFsbCgiLm5hdi1saW5rIiksdCkKcy5LKHMsbmV3IEwuQU8oYikpCkguRGgobSxtLCJUIixvKQpyPW5l
-dyBXLnd6KG4ucXVlcnlTZWxlY3RvckFsbCgiLnJlZ2lvbiIpLHQpCmlmKHIuZ0EocikhPT0wKXtxPW4u
-cXVlcnlTZWxlY3RvcigidGFibGVbZGF0YS1wYXRoXSIpCnEudG9TdHJpbmcKci5LKHIsbmV3IEwuSG8o
-cS5nZXRBdHRyaWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyhxKSkuTygicGF0aCIpKSkpfUgu
-RGgobSxtLCJUIixvKQpwPW5ldyBXLnd6KG4ucXVlcnlTZWxlY3RvckFsbCgiLmFkZC1oaW50LWxpbmsi
-KSx0KQpwLksocCxuZXcgTC5JQygpKX0sClE2OmZ1bmN0aW9uKGEsYil7dmFyIHQ9dS5OCnJldHVybiBX
-LnFEKEwuUTQoYSxiKSxQLkVGKFsiQ29udGVudC1UeXBlIiwiYXBwbGljYXRpb24vanNvbjsgY2hhcnNl
-dD1VVEYtOCJdLHQsdCkpfSwKdHk6ZnVuY3Rpb24oYSl7dmFyIHQ9MCxzPVAuRlgodS5TKSxyLHEscCxv
-LG4sbSxsLGsKdmFyICRhc3luYyR0eT1QLmx6KGZ1bmN0aW9uKGIsYyl7aWYoYj09PTEpcmV0dXJuIFAu
-ZjMoYyxzKQp3aGlsZSh0cnVlKXN3aXRjaCh0KXtjYXNlIDA6bj1uZXcgUC52cygkLlgzLHUuWSkKbT1u
-ZXcgUC5aZihuLHUuRSkKbD1uZXcgWE1MSHR0cFJlcXVlc3QoKQprPXUuTgpDLkR0LmVvKGwsIlBPU1Qi
-LEwuUTQoYSxQLkZsKGssaykpLCEwKQpsLnNldFJlcXVlc3RIZWFkZXIoIkNvbnRlbnQtVHlwZSIsImFw
-cGxpY2F0aW9uL2pzb247IGNoYXJzZXQ9VVRGLTgiKQprPXUuYW4KcT1rLmEobmV3IEwuTDEobSxsKSkK
-dS5NLmEobnVsbCkKcD11LnAKVy5KRShsLCJsb2FkIixxLCExLHApClcuSkUobCwiZXJyb3IiLGsuYSht
-LmdZSigpKSwhMSxwKQpsLnNlbmQoKQp0PTMKcmV0dXJuIFAualEobiwkYXN5bmMkdHkpCmNhc2UgMzpv
-PUMuQ3QucFcoMCxsLnJlc3BvbnNlVGV4dCxudWxsKQppZihsLnN0YXR1cz09PTIwMCl7cj11LlMuYShv
-KQp0PTEKYnJlYWt9ZWxzZSB0aHJvdyBILmIobykKY2FzZSAxOnJldHVybiBQLnlDKHIscyl9fSkKcmV0
-dXJuIFAuREkoJGFzeW5jJHR5LHMpfSwKYUs6ZnVuY3Rpb24oYSl7dmFyIHQ9UC5oSyhhKS5naFkoKS5x
-KDAsImxpbmUiKQpyZXR1cm4gdD09bnVsbD9udWxsOkguSHAodCxudWxsKX0sCkc2OmZ1bmN0aW9uKGEp
-e3ZhciB0PVAuaEsoYSkuZ2hZKCkucSgwLCJvZmZzZXQiKQpyZXR1cm4gdD09bnVsbD9udWxsOkguSHAo
-dCxudWxsKX0sCmk2OmZ1bmN0aW9uKGEpe3JldHVybiBMLm5XKHUuVi5hKGEpKX0sCm5XOmZ1bmN0aW9u
-KGEpe3ZhciB0PTAscz1QLkZYKHUueikscj0xLHEscD1bXSxvLG4sbSxsLGsKdmFyICRhc3luYyRpNj1Q
-Lmx6KGZ1bmN0aW9uKGIsYyl7aWYoYj09PTEpe3E9Ywp0PXJ9d2hpbGUodHJ1ZSlzd2l0Y2godCl7Y2Fz
-ZSAwOmw9dS5oLmEoVy5xYyhhLmN1cnJlbnRUYXJnZXQpKS5nZXRBdHRyaWJ1dGUoImhyZWYiKQphLnBy
-ZXZlbnREZWZhdWx0KCkKcj0zCnQ9NgpyZXR1cm4gUC5qUShMLnR5KGwpLCRhc3luYyRpNikKY2FzZSA2
-OnUuYV8uYShKLkdyKFcuUHYoZG9jdW1lbnQuZGVmYXVsdFZpZXcpKSkucmVsb2FkKCkKcj0xCnQ9NQpi
-cmVhawpjYXNlIDM6cj0yCms9cQpvPUguUnUoaykKbj1ILnRzKGspCkwuQzIoIkNvdWxkIG5vdCBhZGQv
-cmVtb3ZlIGhpbnQiLG8sbikKdD01CmJyZWFrCmNhc2UgMjp0PTEKYnJlYWsKY2FzZSA1OnJldHVybiBQ
-LnlDKG51bGwscykKY2FzZSAxOnJldHVybiBQLmYzKHEscyl9fSkKcmV0dXJuIFAuREkoJGFzeW5jJGk2
-LHMpfSwKQzI6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscj0iZXhjZXB0aW9uIixxPSJzdGFja1RyYWNl
-IixwPXUuUy5iKGIpJiZKLlJNKGIucSgwLCJzdWNjZXNzIiksITEpJiZILm9UKGIueDQocikpJiZILm9U
-KGIueDQocSkpLG89Si5pYShiKQppZihwKXt0PUguYyhvLnEoYixyKSkKYz1vLnEoYixxKX1lbHNlIHQ9
-by5aKGIpCnM9ZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiLnBvcHVwLXBhbmUiKQpzLnF1ZXJ5U2VsZWN0
-b3IoImgyIikuaW5uZXJUZXh0PWEKcy5xdWVyeVNlbGVjdG9yKCJwIikuaW5uZXJUZXh0PXQKcy5xdWVy
-eVNlbGVjdG9yKCJwcmUiKS5pbm5lclRleHQ9Si5BYyhjKQpwPXUuTgp1LmJxLmEocy5xdWVyeVNlbGVj
-dG9yKCJhLmJvdHRvbSIpKS5ocmVmPVAuWGQoImh0dHBzIiwiZ2l0aHViLmNvbSIsImRhcnQtbGFuZy9z
-ZGsvaXNzdWVzL25ldyIsUC5FRihbInRpdGxlIiwiSXNzdWUgd2l0aCBOTkJEIG1pZ3JhdGlvbiB0b29s
-OiAiK2EsImxhYmVscyIsImFyZWEtYW5hbHl6ZXIsYW5hbHl6ZXItbm5iZC1taWdyYXRpb24sdHlwZS1i
-dWciLCJib2R5IixhKyJcblxuRXJyb3I6ICIrSC5kKHQpKyJcblxuUGxlYXNlIGZpbGwgaW4gdGhlIGZv
-bGxvd2luZzpcblxuKipOYW1lIG9mIHBhY2thZ2UgYmVpbmcgbWlncmF0ZWQgKGlmIHB1YmxpYykqKjpc
-bioqV2hhdCBJIHdhcyBkb2luZyB3aGVuIHRoaXMgaXNzdWUgb2NjdXJyZWQqKjpcbioqSXMgaXQgcG9z
-c2libGUgdG8gd29yayBhcm91bmQgdGhpcyBpc3N1ZSoqOlxuKipIYXMgdGhpcyBpc3N1ZSBoYXBwZW5l
-ZCBiZWZvcmUsIGFuZCBpZiBzbywgaG93IG9mdGVuKio6XG4qKkRhcnQgU0RLIHZlcnNpb24qKjogKHZp
-c2libGUgaW4gbG93ZXIgbGVmdCBvZiBtaWdyYXRpb24gcHJldmlldylcbioqQWRkaXRpb25hbCBkZXRh
-aWxzKio6XG5cblRoYW5rcyBmb3IgZmlsaW5nIVxuXG5TdGFja3RyYWNlOiBfYXV0byBwb3B1bGF0ZWQg
-YnkgbWlncmF0aW9uIHByZXZpZXcgdG9vbC5fXG5cbmBgYFxuIitILmQoYykrIlxuYGBgXG4iXSxwLHAp
-KS5nbkQoKQpwPXMuc3R5bGUKcC5kaXNwbGF5PSJpbml0aWFsIgpMLnFKKCJoYW5kbGVQb3N0TGlua0Ns
-aWNrOiAiK0guZChiKSxjKX0sCnQyOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscSxwLG8sbj17fSxt
-PXUuaC5hKFcucWMoYS5jdXJyZW50VGFyZ2V0KSkKYS5wcmV2ZW50RGVmYXVsdCgpCnQ9bi5hPW0uZ2V0
-QXR0cmlidXRlKCJocmVmIikKaWYoSi56bCh0LCI/Iikpe3M9Qy54Qi5Oaih0LDAsQy54Qi5PWSh0LCI/
-IikpCm4uYT1zCnI9c31lbHNlIHI9dAppZihjIT1udWxsKXtxPSQublUoKQpyPW4uYT1xLm81KEQubnIo
-cS50TShjKSxyKSl9cD1MLkc2KHQpCm89TC5hSyh0KQppZihwIT1udWxsKUwuYWYocixwLG8sYixuZXcg
-TC5uVChuLHAsbykpCmVsc2UgTC5hZihyLG51bGwsbnVsbCxiLG5ldyBMLk5ZKG4pKX0sCnZVOmZ1bmN0
-aW9uKCl7dmFyIHQ9ZG9jdW1lbnQscz11LmgKSC5EaChzLHMsIlQiLCJxdWVyeVNlbGVjdG9yQWxsIikK
-dD1uZXcgVy53eih0LnF1ZXJ5U2VsZWN0b3JBbGwoIi5jb2RlIiksdS5UKQp0LksodCxuZXcgTC5HSCgp
-KX0sCmhYOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD11Lk4KTC5RNihhLFAuRUYoWyJyZWdpb24iLCJyZWdp
-b24iLCJvZmZzZXQiLEguZChiKV0sdCx0KSkuVzcobmV3IEwuRFQoYSxiLGMpLHUuUCkuT0EobmV3IEwu
-ZUgoYSkpfSwKRzc6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgdAppZighSi5wNChhLCIuZGFydCIpKXtM
-LkJFKGEsbmV3IEIucXAoIiIsIiIsIiIsQy5DTSksZCkKTC5CWChhLG51bGwpCmlmKGUhPW51bGwpZS4k
-MCgpCnJldHVybn10PXUuTgpMLlE2KGEsUC5FRihbImlubGluZSIsInRydWUiXSx0LHQpKS5XNyhuZXcg
-TC55dShhLGQsYixjLGUpLHUuUCkuT0EobmV3IEwuekQoYSkpfSwKR2U6ZnVuY3Rpb24oKXt2YXIgdD0i
-L19wcmV2aWV3L25hdmlnYXRpb25UcmVlLmpzb24iCkwuUTYodCxDLldPKS5XNyhuZXcgTC5UVygpLHUu
-UCkuT0EobmV3IEwueHIodCkpfSwKcUo6ZnVuY3Rpb24oYSxiKXt2YXIgdAp3aW5kb3cKaWYodHlwZW9m
-IGNvbnNvbGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5jb25zb2xlLmVycm9yKGEpCndpbmRvdwp0PUguZChi
-KQppZih0eXBlb2YgY29uc29sZSE9InVuZGVmaW5lZCIpd2luZG93LmNvbnNvbGUuZXJyb3IodCl9LApx
-TzpmdW5jdGlvbihhKXt2YXIgdCxzPWEuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkscj1DLkNELnpRKCQu
-ZmkoKS5vZmZzZXRIZWlnaHQpLHE9d2luZG93LmlubmVySGVpZ2h0LHA9Qy5DRC56USgkLkRXKCkub2Zm
-c2V0SGVpZ2h0KQppZih0eXBlb2YgcSE9PSJudW1iZXIiKXJldHVybiBxLkhOKCkKdD1zLmJvdHRvbQpp
-Zih0eXBlb2YgdCE9PSJudW1iZXIiKXJldHVybiB0Lm9zKCkKaWYodD5xLShwKzE0KSlKLmRoKGEpCmVs
-c2V7cT1zLnRvcAppZih0eXBlb2YgcSE9PSJudW1iZXIiKXJldHVybiBxLkooKQppZihxPHIrMTQpSi5k
-aChhKX19LApmRzpmdW5jdGlvbihhLGIpe3ZhciB0LHMscgppZihhIT1udWxsKXt0PWRvY3VtZW50CnM9
-dC5nZXRFbGVtZW50QnlJZCgibyIrSC5kKGEpKQpyPXQucXVlcnlTZWxlY3RvcigiLmxpbmUtIitILmQo
-YikpCmlmKHMhPW51bGwpe0wucU8ocykKSi5kUihzKS5pKDAsInRhcmdldCIpfWVsc2UgaWYociE9bnVs
-bClMLnFPKHIucGFyZW50RWxlbWVudCkKaWYociE9bnVsbClKLmRSKHUuaC5hKHIucGFyZW50Tm9kZSkp
-LmkoMCwiaGlnaGxpZ2h0Iil9ZWxzZSBMLnFPKCQuRDkoKSl9LAphZjpmdW5jdGlvbihhLGIsYyxkLGUp
-e3ZhciB0LHMscj1MLkc2KHdpbmRvdy5sb2NhdGlvbi5ocmVmKSxxPUwuYUsod2luZG93LmxvY2F0aW9u
-LmhyZWYpCmlmKHIhPW51bGwpe3Q9ZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoIm8iK0guZChyKSkKaWYo
-dCE9bnVsbClKLmRSKHQpLlIoMCwidGFyZ2V0Iil9aWYocSE9bnVsbCl7cz1kb2N1bWVudC5xdWVyeVNl
-bGVjdG9yKCIubGluZS0iK0guZChxKSkKaWYocyE9bnVsbClKLmRSKHMucGFyZW50RWxlbWVudCkuUigw
-LCJoaWdobGlnaHQiKX1pZihhPT13aW5kb3cubG9jYXRpb24ucGF0aG5hbWUpe0wuZkcoYixjKQplLiQw
-KCl9ZWxzZSBMLkc3KGEsYixjLGQsZSl9LApRNDpmdW5jdGlvbihhLGIpe3ZhciB0LHMscj1QLmhLKGEp
-LHE9dS5OCnE9UC5GbChxLHEpCmZvcih0PXIuZ2hZKCksdD10LmdQdSh0KSx0PXQuZ2t6KHQpO3QuRigp
-Oyl7cz10LmdsKCkKcS5ZKDAscy5hLHMuYil9Zm9yKHQ9Yi5nUHUoYiksdD10Lmdreih0KTt0LkYoKTsp
-e3M9dC5nbCgpCnEuWSgwLHMuYSxzLmIpfXEuWSgwLCJhdXRoVG9rZW4iLCQuVUUoKSkKcmV0dXJuIHIu
-bm0oMCxxKS5nbkQoKX0sClQxOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrPSQuaEwo
-KQpKLmw1KGssIiIpCmlmKGE9PW51bGwpe3Q9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgicCIpCnQudGV4
-dENvbnRlbnQ9IlNlZSBkZXRhaWxzIGFib3V0IGEgcHJvcG9zZWQgZWRpdC4iCkMuTHQuc1AodCxILlZN
-KFsicGxhY2Vob2xkZXIiXSx1LnMpKQprLmFwcGVuZENoaWxkKHQpCkMuTHQuRkYodCkKcmV0dXJufXM9
-YS5kCnI9JC5uVSgpCnE9ci50TShzKQpwPWEuYgpvPWRvY3VtZW50Cm49ci5IUChzLEouVDAoby5xdWVy
-eVNlbGVjdG9yKCIucm9vdCIpLnRleHRDb250ZW50KSkKbT1hLmMKbD1vLmNyZWF0ZUVsZW1lbnQoInAi
-KQprLmFwcGVuZENoaWxkKGwpCmwuYXBwZW5kQ2hpbGQoby5jcmVhdGVUZXh0Tm9kZShILmQocCkrIiBh
-dCAiK0guZChuKSsiOiIrSC5kKG0pKyIuIikpCkouZGgobCkKTC5DQyhhLGsscSkKTC5GeihhLGspfSwK
-TEg6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGc9JC55UCgpCkou
-bDUoZywiIikKaWYoYi5nQShiKT09PTApe3Q9ZG9jdW1lbnQKcz10LmNyZWF0ZUVsZW1lbnQoInAiKQpn
-LmFwcGVuZENoaWxkKHMpCnMuYXBwZW5kQ2hpbGQodC5jcmVhdGVUZXh0Tm9kZSgiTm8gcHJvcG9zZWQg
-ZWRpdHMiKSl9ZWxzZSBmb3IoZz1iLmdQdShiKSxnPWcuZ2t6KGcpLHQ9dS5RLHI9dC5DKCJ+KDEpIiks
-cT11Lk0sdD10LmM7Zy5GKCk7KXtwPWcuZ2woKQpvPWRvY3VtZW50CnM9by5jcmVhdGVFbGVtZW50KCJw
-IikKbj0kLnlQKCkKbi5hcHBlbmRDaGlsZChzKQpzLmFwcGVuZENoaWxkKG8uY3JlYXRlVGV4dE5vZGUo
-SC5kKHAuYSkrIjoiKSkKbT1vLmNyZWF0ZUVsZW1lbnQoInVsIikKbi5hcHBlbmRDaGlsZChtKQpmb3Io
-cD1KLklUKHAuYik7cC5GKCk7KXtuPXAuZ2woKQpsPW8uY3JlYXRlRWxlbWVudCgibGkiKQptLmFwcGVu
-ZENoaWxkKGwpCkouZFIobCkuaSgwLCJlZGl0IikKaz1vLmNyZWF0ZUVsZW1lbnQoImEiKQpsLmFwcGVu
-ZENoaWxkKGspCmsuY2xhc3NMaXN0LmFkZCgiZWRpdC1saW5rIikKaj1uLmMKaT1ILmQoaikKay5zZXRB
-dHRyaWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyhrKSkuTygib2Zmc2V0IiksaSkKaD1uLmEK
-aT1ILmQoaCkKay5zZXRBdHRyaWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyhrKSkuTygibGlu
-ZSIpLGkpCmsuYXBwZW5kQ2hpbGQoby5jcmVhdGVUZXh0Tm9kZSgibGluZSAiK0guZChoKSkpCmk9ci5h
-KG5ldyBMLkVFKGosaCxhKSkKcS5hKG51bGwpClcuSkUoaywiY2xpY2siLGksITEsdCkKbC5hcHBlbmRD
-aGlsZChvLmNyZWF0ZVRleHROb2RlKCI6ICIrSC5kKG4uYikpKX19aWYoYylMLlQxKG51bGwpfSwKRnI6
-ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscj13aW5kb3cubG9jYXRpb24scT1QLmhLKChyJiZDLkV4KS5n
-RHIocikrSC5kKGEpKQpyPXUuTgpyPVAuRmwocixyKQppZihiIT1udWxsKXIuWSgwLCJvZmZzZXQiLEgu
-ZChiKSkKaWYoYyE9bnVsbClyLlkoMCwibGluZSIsSC5kKGMpKQpyLlkoMCwiYXV0aFRva2VuIiwkLlVF
-KCkpCnE9cS5ubSgwLHIpCnI9d2luZG93Lmhpc3RvcnkKdD11LnoKcz1xLmduRCgpCnIudG9TdHJpbmcK
-ci5wdXNoU3RhdGUobmV3IFAuQmYoW10sW10pLlB2KFAuRmwodCx0KSksIiIscyl9LApFbjpmdW5jdGlv
-bihhKXt2YXIgdD1KLm0oZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiLnJvb3QiKS50ZXh0Q29udGVudCwi
-LyIpCmlmKEMueEIubihhLHQpKXJldHVybiBDLnhCLkcoYSx0Lmxlbmd0aCkKZWxzZSByZXR1cm4gYX0s
-CkJYOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyPXt9CnIuYT1hCmE9TC5FbihhKQpyLmE9YQokLkQ5KCku
-dGV4dENvbnRlbnQ9YQp0PWRvY3VtZW50CnM9dS5oCkguRGgocyxzLCJUIiwicXVlcnlTZWxlY3RvckFs
-bCIpCnQ9bmV3IFcud3oodC5xdWVyeVNlbGVjdG9yQWxsKCIubmF2LXBhbmVsIC5uYXYtbGluayIpLHUu
-VCkKdC5LKHQsbmV3IEwuVlMocikpfSwKQkU6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PSIucmVnaW9ucyIs
-cz1kb2N1bWVudCxyPXMucXVlcnlTZWxlY3Rvcih0KSxxPXMucXVlcnlTZWxlY3RvcigiLmNvZGUiKQpK
-LnRIKHIsYi5hLCQuS0coKSkKSi50SChxLGIuYiwkLktHKCkpCkwuTEgoYSxiLmQsYykKTC52VSgpCkwu
-eVgoIi5jb2RlIiwhMCkKTC55WCh0LCEwKX0sCnRYOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxv
-LG4sbSxsLGssaixpLGgsZz1kb2N1bWVudCxmPWcuY3JlYXRlRWxlbWVudCgidWwiKQphLmFwcGVuZENo
-aWxkKGYpCmZvcih0PWIubGVuZ3RoLHM9dS5NLHI9MDtyPGIubGVuZ3RoO2IubGVuZ3RoPT09dHx8KDAs
-SC5saykoYiksKytyKXtxPWJbcl0KcD1nLmNyZWF0ZUVsZW1lbnQoImxpIikKZi5hcHBlbmRDaGlsZChw
-KQpvPUouUkUocCkKaWYocS5hPT09Qy5ZMil7by5nUChwKS5pKDAsImRpciIpCm49Zy5jcmVhdGVFbGVt
-ZW50KCJzcGFuIikKcC5hcHBlbmRDaGlsZChuKQpvPUouUkUobikKby5nUChuKS5pKDAsImFycm93IikK
-by5zaGYobiwiJiN4MjVCQzsiKQptPWcuY3JlYXRlRWxlbWVudCgic3BhbiIpCnAuYXBwZW5kQ2hpbGQo
-bSkKSi5sNShtLCImI3gxRjRDMTsiKQpwLmFwcGVuZENoaWxkKGcuY3JlYXRlVGV4dE5vZGUocS5iKSkK
-TC50WChwLHEuYykKTC5reihuKX1lbHNle28uc2hmKHAsIiYjeDFGNEM0OyIpCmw9Zy5jcmVhdGVFbGVt
-ZW50KCJhIikKcC5hcHBlbmRDaGlsZChsKQpvPUouUkUobCkKby5nUChsKS5pKDAsIm5hdi1saW5rIikK
-bC5zZXRBdHRyaWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyhsKSkuTygibmFtZSIpLHEuZCkK
-bC5zZXRBdHRyaWJ1dGUoImhyZWYiLHEuZSkKbC5hcHBlbmRDaGlsZChnLmNyZWF0ZVRleHROb2RlKHEu
-YikpCm89by5nVmwobCkKaz1vLiR0aQpqPWsuQygifigxKSIpLmEobmV3IEwuVEQoKSkKcy5hKG51bGwp
-ClcuSkUoby5hLG8uYixqLCExLGsuYykKaT1xLmYKaWYodHlwZW9mIGkhPT0ibnVtYmVyIilyZXR1cm4g
-aS5vcygpCmlmKGk+MCl7aD1nLmNyZWF0ZUVsZW1lbnQoInNwYW4iKQpwLmFwcGVuZENoaWxkKGgpCkou
-ZFIoaCkuaSgwLCJlZGl0LWNvdW50IikKbz0iIitpKyIgIgppZihpPT09MSlrPSJlZGl0IgplbHNlIGs9
-ImVkaXRzIgpoLnNldEF0dHJpYnV0ZSgidGl0bGUiLG8raykKaC5hcHBlbmRDaGlsZChnLmNyZWF0ZVRl
-eHROb2RlKEMuam4uWihpKSkpfX19fSwKRno6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG8sbixt
-LGwsayxqPWEuYQppZihqIT1udWxsKXt0PWRvY3VtZW50CnM9dC5jcmVhdGVFbGVtZW50KCJwIikKYi5h
-cHBlbmRDaGlsZChzKQpmb3Iocj1qLmxlbmd0aCxxPXUucyxwPXUuWCxvPTA7bzxqLmxlbmd0aDtqLmxl
-bmd0aD09PXJ8fCgwLEgubGspKGopLCsrbyl7bj1qW29dCm09dC5jcmVhdGVFbGVtZW50KCJhIikKcy5h
-cHBlbmRDaGlsZChtKQptLmFwcGVuZENoaWxkKHQuY3JlYXRlVGV4dE5vZGUobi5hKSkKbS5zZXRBdHRy
-aWJ1dGUoImhyZWYiLG4uYikKbD1wLmEoSC5WTShbImFkZC1oaW50LWxpbmsiLCJiZWZvcmUtYXBwbHki
-LCJidXR0b24iXSxxKSkKaz1KLmRSKG0pCmsuVjEoMCkKay5GVigwLGwpfX19LApDQzpmdW5jdGlvbihh
-MixhMyxhNCl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixpLGgsZyxmLGUsZCxjLGIsYSxhMCxhMT1u
-dWxsCmZvcih0PWEyLmUscz10Lmxlbmd0aCxyPXUucyxxPXUuWCxwPTA7cDx0Lmxlbmd0aDt0Lmxlbmd0
-aD09PXN8fCgwLEgubGspKHQpLCsrcCl7bz10W3BdCm49ZG9jdW1lbnQKbT1uLmNyZWF0ZUVsZW1lbnQo
-InAiKQpsPXEuYShILlZNKFsidHJhY2UiXSxyKSkKaz1KLmRSKG0pCmsuVjEoMCkKay5GVigwLGwpCmo9
-YTMuYXBwZW5kQ2hpbGQobSkKbT1uLmNyZWF0ZUVsZW1lbnQoInNwYW4iKQpsPXEuYShILlZNKFsidHlw
-ZS1kZXNjcmlwdGlvbiJdLHIpKQprPUouZFIobSkKay5WMSgwKQprLkZWKDAsbCkKbS5hcHBlbmRDaGls
-ZChuLmNyZWF0ZVRleHROb2RlKG8uYSkpCmouYXBwZW5kQ2hpbGQobSkKai5hcHBlbmRDaGlsZChuLmNy
-ZWF0ZVRleHROb2RlKCI6IikpCm09bi5jcmVhdGVFbGVtZW50KCJ1bCIpCmw9cS5hKEguVk0oWyJ0cmFj
-ZSJdLHIpKQprPUouZFIobSkKay5WMSgwKQprLkZWKDAsbCkKaT1qLmFwcGVuZENoaWxkKG0pCmZvciht
-PW8uYixsPW0ubGVuZ3RoLGg9MDtoPG0ubGVuZ3RoO20ubGVuZ3RoPT09bHx8KDAsSC5saykobSksKyto
-KXtnPW1baF0KZj1uLmNyZWF0ZUVsZW1lbnQoImxpIikKSi5sNShmLCImI3gyNzRGOyAiKQppLmFwcGVu
-ZENoaWxkKGYpCmU9bi5jcmVhdGVFbGVtZW50KCJzcGFuIikKZD1xLmEoSC5WTShbImZ1bmN0aW9uIl0s
-cikpCms9Si5kUihlKQprLlYxKDApCmsuRlYoMCxkKQpkPWcuYgpMLmtEKGUsZD09bnVsbD8idW5rbm93
-biI6ZCkKZi5hcHBlbmRDaGlsZChlKQpjPWcuYwppZihjIT1udWxsKXtmLmFwcGVuZENoaWxkKG4uY3Jl
-YXRlVGV4dE5vZGUoIiAoIikpCmI9Yy5iCmE9bi5jcmVhdGVFbGVtZW50KCJhIikKYS5hcHBlbmRDaGls
-ZChuLmNyZWF0ZVRleHROb2RlKEguZChjLmMpKyI6IitILmQoYikpKQphMD1jLmEKZT0kLm5VKCkKYS5z
-ZXRBdHRyaWJ1dGUoImhyZWYiLGUubzUoZS5xNygwLGE0LGEwLGExLGExLGExLGExLGExLGExKSkpCmEu
-Y2xhc3NMaXN0LmFkZCgibmF2LWxpbmsiKQpmLmFwcGVuZENoaWxkKGEpCmYuYXBwZW5kQ2hpbGQobi5j
-cmVhdGVUZXh0Tm9kZSgiKSIpKX1mLmFwcGVuZENoaWxkKG4uY3JlYXRlVGV4dE5vZGUoIjogIikpCmU9
-Zy5hCkwua0QoZixlPT1udWxsPyJ1bmtub3duIjplKX19fSwKa0Q6ZnVuY3Rpb24oYSxiKXt2YXIgdCxz
-LHI9SC5WTShiLnNwbGl0KCIuIiksdS5zKSxxPUMuTm0uZ3RIKHIpLHA9ZG9jdW1lbnQKYS5hcHBlbmRD
-aGlsZChwLmNyZWF0ZVRleHROb2RlKHEpKQpmb3IocT1ILnFDKHIsMSxudWxsLHUuTikscT1uZXcgSC5h
-NyhxLHEuZ0EocSkscS4kdGkuQygiYTc8YUwuRT4iKSksdD1KLlJFKGEpO3EuRigpOyl7cz1xLmQKdC5u
-eihhLCJiZWZvcmVlbmQiLCImIzgyMDM7LiIsbnVsbCxudWxsKQphLmFwcGVuZENoaWxkKHAuY3JlYXRl
-VGV4dE5vZGUocykpfX0sCmU6ZnVuY3Rpb24gZSgpe30sClZXOmZ1bmN0aW9uIFZXKGEsYixjKXt0aGlz
-LmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCm9aOmZ1bmN0aW9uIG9aKCl7fSwKanI6ZnVuY3Rpb24ganIo
-KXt9LApxbDpmdW5jdGlvbiBxbCgpe30sCnk4OmZ1bmN0aW9uIHk4KCl7fSwKSGk6ZnVuY3Rpb24gSGko
-KXt9LApCVDpmdW5jdGlvbiBCVCgpe30sCkw6ZnVuY3Rpb24gTCgpe30sCld4OmZ1bmN0aW9uIFd4KGEs
-Yil7dGhpcy5hPWEKdGhpcy5iPWJ9LApBTzpmdW5jdGlvbiBBTyhhKXt0aGlzLmE9YX0sCmROOmZ1bmN0
-aW9uIGROKGEpe3RoaXMuYT1hfSwKSG86ZnVuY3Rpb24gSG8oYSl7dGhpcy5hPWF9LAp4ejpmdW5jdGlv
-biB4eihhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKSUM6ZnVuY3Rpb24gSUMoKXt9LApMMTpmdW5jdGlv
-biBMMShhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKblQ6ZnVuY3Rpb24gblQoYSxiLGMpe3RoaXMuYT1h
-CnRoaXMuYj1iCnRoaXMuYz1jfSwKTlk6ZnVuY3Rpb24gTlkoYSl7dGhpcy5hPWF9LApHSDpmdW5jdGlv
-biBHSCgpe30sCkRUOmZ1bmN0aW9uIERUKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30s
-CmVIOmZ1bmN0aW9uIGVIKGEpe3RoaXMuYT1hfSwKeXU6ZnVuY3Rpb24geXUoYSxiLGMsZCxlKXt2YXIg
-Xz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kCl8uZT1lfSwKekQ6ZnVuY3Rpb24gekQoYSl7dGhp
-cy5hPWF9LApUVzpmdW5jdGlvbiBUVygpe30sCnhyOmZ1bmN0aW9uIHhyKGEpe3RoaXMuYT1hfSwKRUU6
-ZnVuY3Rpb24gRUUoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKUUw6ZnVuY3Rpb24g
-UUwoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sClZTOmZ1bmN0aW9uIFZTKGEpe3RoaXMuYT1hfSwKVEQ6
-ZnVuY3Rpb24gVEQoKXt9LApYQTpmdW5jdGlvbiBYQSgpe30sCm1LOmZ1bmN0aW9uKGEpe3ZhciB0LHMs
-cixxLHAsbyxuPUguVk0oW10sdS5maCkKZm9yKHQ9Si5JVCh1LlIuYShhKSk7dC5GKCk7KXtzPXQuZ2wo
-KQpyPUouVTYocykKcT1MLnAyKEguYyhyLnEocywidHlwZSIpKSkKcD1ILmMoci5xKHMsIm5hbWUiKSkK
-bz1yLnEocywic3VidHJlZSIpCm89bz09bnVsbD9udWxsOkwubUsobykKQy5ObS5pKG4sbmV3IEwuWloo
-cSxwLG8sSC5jKHIucShzLCJwYXRoIikpLEguYyhyLnEocywiaHJlZiIpKSxILldZKHIucShzLCJlZGl0
-Q291bnQiKSkpKX1yZXR1cm4gbn0sCnAyOmZ1bmN0aW9uKGEpe3N3aXRjaChhKXtjYXNlImRpcmVjdG9y
-eSI6cmV0dXJuIEMuWTIKY2FzZSJmaWxlIjpyZXR1cm4gQy5yZgpkZWZhdWx0OnRocm93IEguYihQLlBW
-KCJVbnJlY29nbml6ZWQgbmF2aWdhdGlvbiB0cmVlIG5vZGUgdHlwZTogIitILmQoYSkpKX19LApaWjpm
-dW5jdGlvbiBaWihhLGIsYyxkLGUsZil7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZApf
-LmU9ZQpfLmY9Zn0sCk85OmZ1bmN0aW9uIE85KGEpe3RoaXMuYj1hfSwKSVY6ZnVuY3Rpb24gSVYoYSxi
-LGMsZCl7dmFyIF89dGhpcwpfLmQ9YQpfLmU9YgpfLmY9YwpfLnI9ZH19LE09ewpZRjpmdW5jdGlvbihh
-LGIpe3ZhciB0LHMscixxLHAsbyxuCmZvcih0PWIubGVuZ3RoLHM9MTtzPHQ7KytzKXtpZihiW3NdPT1u
-dWxsfHxiW3MtMV0hPW51bGwpY29udGludWUKZm9yKDt0Pj0xO3Q9cil7cj10LTEKaWYoYltyXSE9bnVs
-bClicmVha31xPW5ldyBQLlJuKCIiKQpwPWErIigiCnEuYT1wCm89SC5xQyhiLDAsdCxILnQ2KGIpLmMp
-Cm49by4kdGkKbj1wK25ldyBILmxKKG8sbi5DKCJxVShhTC5FKSIpLmEobmV3IE0uTm8oKSksbi5DKCJs
-SjxhTC5FLHFVPiIpKS56VigwLCIsICIpCnEuYT1uCnEuYT1uKygiKTogcGFydCAiKyhzLTEpKyIgd2Fz
-IG51bGwsIGJ1dCBwYXJ0ICIrcysiIHdhcyBub3QuIikKdGhyb3cgSC5iKFAueFkocS5aKDApKSl9fSwK
-bEk6ZnVuY3Rpb24gbEkoYSl7dGhpcy5hPWF9LApNaTpmdW5jdGlvbiBNaSgpe30sCnE3OmZ1bmN0aW9u
-IHE3KCl7fSwKTm86ZnVuY3Rpb24gTm8oKXt9fSxYPXsKQ0w6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIs
-cSxwLG89Yi54WihhKQpiLmhLKGEpCmlmKG8hPW51bGwpYT1KLktWKGEsby5sZW5ndGgpCnQ9dS5zCnM9
-SC5WTShbXSx0KQpyPUguVk0oW10sdCkKdD1hLmxlbmd0aAppZih0IT09MCYmYi5yNChDLnhCLlcoYSww
-KSkpe2lmKDA+PXQpcmV0dXJuIEguayhhLDApCkMuTm0uaShyLGFbMF0pCnE9MX1lbHNle0MuTm0uaShy
-LCIiKQpxPTB9Zm9yKHA9cTtwPHQ7KytwKWlmKGIucjQoQy54Qi5XKGEscCkpKXtDLk5tLmkocyxDLnhC
-Lk5qKGEscSxwKSkKQy5ObS5pKHIsYVtwXSkKcT1wKzF9aWYocTx0KXtDLk5tLmkocyxDLnhCLkcoYSxx
-KSkKQy5ObS5pKHIsIiIpfXJldHVybiBuZXcgWC5XRChiLG8scyxyKX0sCldEOmZ1bmN0aW9uIFdEKGEs
-YixjLGQpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5kPWMKXy5lPWR9LApxUjpmdW5jdGlvbiBxUihh
-KXt0aGlzLmE9YX0sCkk3OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgWC5kdihhKX0sCmR2OmZ1bmN0aW9u
-IGR2KGEpe3RoaXMuYT1hfX0sTz17ClJoOmZ1bmN0aW9uKCl7dmFyIHQscz1udWxsCmlmKFAudW8oKS5n
-RmkoKSE9PSJmaWxlIilyZXR1cm4gJC5FYigpCnQ9UC51bygpCmlmKCFDLnhCLlRjKHQuZ0lpKHQpLCIv
-IikpcmV0dXJuICQuRWIoKQppZihQLktMKHMsImEvYiIscyxzLHMscyxzKS50NCgpPT09ImFcXGIiKXJl
-dHVybiAkLktrKCkKcmV0dXJuICQuYkQoKX0sCnpMOmZ1bmN0aW9uIHpMKCl7fX0sRT17T0Y6ZnVuY3Rp
-b24gT0YoYSxiLGMpe3RoaXMuZD1hCnRoaXMuZT1iCnRoaXMuZj1jfX0sRj17cnU6ZnVuY3Rpb24gcnUo
-YSxiLGMsZCl7dmFyIF89dGhpcwpfLmQ9YQpfLmU9YgpfLmY9YwpfLnI9ZH19LEQ9ewpSWDpmdW5jdGlv
-bigpe3ZhciB0LHMscj1QLnVvKCkKaWYoci5ETigwLCQuSTYpKXJldHVybiAkLkZmCiQuSTY9cgppZigk
-LkhrKCk9PSQuRWIoKSlyZXR1cm4gJC5GZj1yLlpJKCIuIikuWigwKQplbHNle3Q9ci50NCgpCnM9dC5s
-ZW5ndGgtMQpyZXR1cm4gJC5GZj1zPT09MD90OkMueEIuTmoodCwwLHMpfX0sCm5yOmZ1bmN0aW9uKGEs
-Yil7dmFyIHQ9bnVsbApyZXR1cm4gJC5uVSgpLnE3KDAsYSxiLHQsdCx0LHQsdCx0KX19CnZhciB3PVtD
-LEgsSixQLFcsVSxCLFQsTCxNLFgsTyxFLEYsRF0KaHVua0hlbHBlcnMuc2V0RnVuY3Rpb25OYW1lc0lm
-TmVjZXNzYXJ5KHcpCnZhciAkPXt9CkguRksucHJvdG90eXBlPXt9CkoudkIucHJvdG90eXBlPXsKRE46
-ZnVuY3Rpb24oYSxiKXtyZXR1cm4gYT09PWJ9LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJuIEguZVEoYSl9
-LApaOmZ1bmN0aW9uKGEpe3JldHVybiJJbnN0YW5jZSBvZiAnIitILmQoSC5saChhKSkrIicifSwKZTc6
-ZnVuY3Rpb24oYSxiKXt1Lm8uYShiKQp0aHJvdyBILmIoUC5scihhLGIuZ1dhKCksYi5nbmQoKSxiLmdW
-bSgpKSl9fQpKLnlFLnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7cmV0dXJuIFN0cmluZyhhKX0sCmdp
-TzpmdW5jdGlvbihhKXtyZXR1cm4gYT81MTkwMTg6MjE4MTU5fSwKJGlhMjoxfQpKLllFLnByb3RvdHlw
-ZT17CkROOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG51bGw9PWJ9LApaOmZ1bmN0aW9uKGEpe3JldHVybiJu
-dWxsIn0sCmdpTzpmdW5jdGlvbihhKXtyZXR1cm4gMH0sCmU3OmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRo
-aXMuU2ooYSx1Lm8uYShiKSl9LAokaWM4OjF9CkouTUYucHJvdG90eXBlPXsKZ2lPOmZ1bmN0aW9uKGEp
-e3JldHVybiAwfSwKWjpmdW5jdGlvbihhKXtyZXR1cm4gU3RyaW5nKGEpfSwKJGl2bToxfQpKLmlDLnBy
-b3RvdHlwZT17fQpKLmtkLnByb3RvdHlwZT17fQpKLmM1LnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7
-dmFyIHQ9YVskLndRKCldCmlmKHQ9PW51bGwpcmV0dXJuIHRoaXMudChhKQpyZXR1cm4iSmF2YVNjcmlw
-dCBmdW5jdGlvbiBmb3IgIitILmQoSi5BYyh0KSl9LAokUzpmdW5jdGlvbigpe3JldHVybntmdW5jOjEs
-b3B0OlssLCwsLCwsLCwsLCwsLCwsXX19LAokaUVIOjF9CkouamQucHJvdG90eXBlPXsKaTpmdW5jdGlv
-bihhLGIpe0gudDYoYSkuYy5hKGIpCmlmKCEhYS5maXhlZCRsZW5ndGgpSC52aChQLkw0KCJhZGQiKSkK
-YS5wdXNoKGIpfSwKVzQ6ZnVuY3Rpb24oYSxiKXt2YXIgdAppZighIWEuZml4ZWQkbGVuZ3RoKUgudmgo
-UC5MNCgicmVtb3ZlQXQiKSkKdD1hLmxlbmd0aAppZihiPj10KXRocm93IEguYihQLk83KGIsbnVsbCkp
-CnJldHVybiBhLnNwbGljZShiLDEpWzBdfSwKVUc6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscgpILnQ2
-KGEpLkMoImNYPDE+IikuYShjKQppZighIWEuZml4ZWQkbGVuZ3RoKUgudmgoUC5MNCgiaW5zZXJ0QWxs
-IikpCnQ9YS5sZW5ndGgKUC53QShiLDAsdCwiaW5kZXgiKQpzPWMubGVuZ3RoCnRoaXMuc0EoYSx0K3Mp
-CnI9YitzCnRoaXMuWVcoYSxyLGEubGVuZ3RoLGEsYikKdGhpcy52ZyhhLGIscixjKX0sCm12OmZ1bmN0
-aW9uKGEpe2lmKCEhYS5maXhlZCRsZW5ndGgpSC52aChQLkw0KCJyZW1vdmVMYXN0IikpCmlmKGEubGVu
-Z3RoPT09MCl0aHJvdyBILmIoSC5IWShhLC0xKSkKcmV0dXJuIGEucG9wKCl9LApGVjpmdW5jdGlvbihh
-LGIpe3ZhciB0CkgudDYoYSkuQygiY1g8MT4iKS5hKGIpCmlmKCEhYS5maXhlZCRsZW5ndGgpSC52aChQ
-Lkw0KCJhZGRBbGwiKSkKZm9yKHQ9Si5JVChiKTt0LkYoKTspYS5wdXNoKHQuZ2woKSl9LApFMjpmdW5j
-dGlvbihhLGIsYyl7dmFyIHQ9SC50NihhKQpyZXR1cm4gbmV3IEgubEooYSx0LktxKGMpLkMoIjEoMiki
-KS5hKGIpLHQuQygiQDwxPiIpLktxKGMpLkMoImxKPDEsMj4iKSl9LAp6VjpmdW5jdGlvbihhLGIpe3Zh
-ciB0LHM9UC5POChhLmxlbmd0aCwiIiwhMSx1Lk4pCmZvcih0PTA7dDxhLmxlbmd0aDsrK3QpdGhpcy5Z
-KHMsdCxILmQoYVt0XSkpCnJldHVybiBzLmpvaW4oYil9LApOMDpmdW5jdGlvbihhLGIsYyxkKXt2YXIg
-dCxzLHIKZC5hKGIpCkgudDYoYSkuS3EoZCkuQygiMSgxLDIpIikuYShjKQp0PWEubGVuZ3RoCmZvcihz
-PWIscj0wO3I8dDsrK3Ipe3M9Yy4kMihzLGFbcl0pCmlmKGEubGVuZ3RoIT09dCl0aHJvdyBILmIoUC5h
-NChhKSl9cmV0dXJuIHN9LApFOmZ1bmN0aW9uKGEsYil7aWYoYjwwfHxiPj1hLmxlbmd0aClyZXR1cm4g
-SC5rKGEsYikKcmV0dXJuIGFbYl19LApENjpmdW5jdGlvbihhLGIsYyl7aWYoYjwwfHxiPmEubGVuZ3Ro
-KXRocm93IEguYihQLlRFKGIsMCxhLmxlbmd0aCwic3RhcnQiLG51bGwpKQppZihjPGJ8fGM+YS5sZW5n
-dGgpdGhyb3cgSC5iKFAuVEUoYyxiLGEubGVuZ3RoLCJlbmQiLG51bGwpKQppZihiPT09YylyZXR1cm4g
-SC5WTShbXSxILnQ2KGEpKQpyZXR1cm4gSC5WTShhLnNsaWNlKGIsYyksSC50NihhKSl9LApndEg6ZnVu
-Y3Rpb24oYSl7aWYoYS5sZW5ndGg+MClyZXR1cm4gYVswXQp0aHJvdyBILmIoSC5XcCgpKX0sCmdyWjpm
-dW5jdGlvbihhKXt2YXIgdD1hLmxlbmd0aAppZih0PjApcmV0dXJuIGFbdC0xXQp0aHJvdyBILmIoSC5X
-cCgpKX0sCllXOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHQscyxyLHEscD1ILnQ2KGEpCnAuQygiY1g8
-MT4iKS5hKGQpCmlmKCEhYS5pbW11dGFibGUkbGlzdClILnZoKFAuTDQoInNldFJhbmdlIikpClAuakIo
-YixjLGEubGVuZ3RoKQp0PWMtYgppZih0PT09MClyZXR1cm4KUC5rMShlLCJza2lwQ291bnQiKQppZihw
-LkMoInpNPDE+IikuYihkKSl7cz1lCnI9ZH1lbHNle3I9SC5xQyhkLGUsbnVsbCxILnQ2KGQpLmMpLnR0
-KDAsITEpCnM9MH1pZihzK3Q+ci5sZW5ndGgpdGhyb3cgSC5iKEguYXIoKSkKaWYoczxiKWZvcihxPXQt
-MTtxPj0wOy0tcSl7cD1zK3EKaWYocD49ci5sZW5ndGgpcmV0dXJuIEguayhyLHApCmFbYitxXT1yW3Bd
-fWVsc2UgZm9yKHE9MDtxPHQ7KytxKXtwPXMrcQppZihwPj1yLmxlbmd0aClyZXR1cm4gSC5rKHIscCkK
-YVtiK3FdPXJbcF19fSwKdmc6ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJuIHRoaXMuWVcoYSxiLGMsZCww
-KX0sClZyOmZ1bmN0aW9uKGEsYil7dmFyIHQscwpILnQ2KGEpLkMoImEyKDEpIikuYShiKQp0PWEubGVu
-Z3RoCmZvcihzPTA7czx0Oysrcyl7aWYoSC5vVChiLiQxKGFbc10pKSlyZXR1cm4hMAppZihhLmxlbmd0
-aCE9PXQpdGhyb3cgSC5iKFAuYTQoYSkpfXJldHVybiExfSwKdGc6ZnVuY3Rpb24oYSxiKXt2YXIgdApm
-b3IodD0wO3Q8YS5sZW5ndGg7Kyt0KWlmKEouUk0oYVt0XSxiKSlyZXR1cm4hMApyZXR1cm4hMX0sClo6
-ZnVuY3Rpb24oYSl7cmV0dXJuIFAuV0UoYSwiWyIsIl0iKX0sCmdrejpmdW5jdGlvbihhKXtyZXR1cm4g
-bmV3IEoubTEoYSxhLmxlbmd0aCxILnQ2KGEpLkMoIm0xPDE+IikpfSwKZ2lPOmZ1bmN0aW9uKGEpe3Jl
-dHVybiBILmVRKGEpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwKc0E6ZnVuY3Rpb24o
-YSxiKXtpZighIWEuZml4ZWQkbGVuZ3RoKUgudmgoUC5MNCgic2V0IGxlbmd0aCIpKQphLmxlbmd0aD1i
-fSwKcTpmdW5jdGlvbihhLGIpe0guV1koYikKaWYoYj49YS5sZW5ndGh8fGI8MCl0aHJvdyBILmIoSC5I
-WShhLGIpKQpyZXR1cm4gYVtiXX0sClk6ZnVuY3Rpb24oYSxiLGMpe0gudDYoYSkuYy5hKGMpCmlmKCEh
-YS5pbW11dGFibGUkbGlzdClILnZoKFAuTDQoImluZGV4ZWQgc2V0IikpCmlmKGI+PWEubGVuZ3RofHxi
-PDApdGhyb3cgSC5iKEguSFkoYSxiKSkKYVtiXT1jfSwKJGliUToxLAokaWNYOjEsCiRpek06MX0KSi5Q
-by5wcm90b3R5cGU9e30KSi5tMS5wcm90b3R5cGU9ewpnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmR9
-LApGOmZ1bmN0aW9uKCl7dmFyIHQscz10aGlzLHI9cy5hLHE9ci5sZW5ndGgKaWYocy5iIT09cSl0aHJv
-dyBILmIoSC5sayhyKSkKdD1zLmMKaWYodD49cSl7cy5zSChudWxsKQpyZXR1cm4hMX1zLnNIKHJbdF0p
-Oysrcy5jCnJldHVybiEwfSwKc0g6ZnVuY3Rpb24oYSl7dGhpcy5kPXRoaXMuJHRpLmMuYShhKX0sCiRp
-QW46MX0KSi5xSS5wcm90b3R5cGU9ewp6UTpmdW5jdGlvbihhKXtpZihhPjApe2lmKGEhPT0xLzApcmV0
-dXJuIE1hdGgucm91bmQoYSl9ZWxzZSBpZihhPi0xLzApcmV0dXJuIDAtTWF0aC5yb3VuZCgwLWEpCnRo
-cm93IEguYihQLkw0KCIiK2ErIi5yb3VuZCgpIikpfSwKV1o6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIs
-cQppZihiPDJ8fGI+MzYpdGhyb3cgSC5iKFAuVEUoYiwyLDM2LCJyYWRpeCIsbnVsbCkpCnQ9YS50b1N0
-cmluZyhiKQppZihDLnhCLm0odCx0Lmxlbmd0aC0xKSE9PTQxKXJldHVybiB0CnM9L14oW1xkYS16XSsp
-KD86XC4oW1xkYS16XSspKT9cKGVcKyhcZCspXCkkLy5leGVjKHQpCmlmKHM9PW51bGwpSC52aChQLkw0
-KCJVbmV4cGVjdGVkIHRvU3RyaW5nIHJlc3VsdDogIit0KSkKcj1zLmxlbmd0aAppZigxPj1yKXJldHVy
-biBILmsocywxKQp0PXNbMV0KaWYoMz49cilyZXR1cm4gSC5rKHMsMykKcT0rc1szXQpyPXNbMl0KaWYo
-ciE9bnVsbCl7dCs9cgpxLT1yLmxlbmd0aH1yZXR1cm4gdCtDLnhCLkl4KCIwIixxKX0sClo6ZnVuY3Rp
-b24oYSl7aWYoYT09PTAmJjEvYTwwKXJldHVybiItMC4wIgplbHNlIHJldHVybiIiK2F9LApnaU86ZnVu
-Y3Rpb24oYSl7dmFyIHQscyxyLHEscD1hfDAKaWYoYT09PXApcmV0dXJuIDUzNjg3MDkxMSZwCnQ9TWF0
-aC5hYnMoYSkKcz1NYXRoLmxvZyh0KS8wLjY5MzE0NzE4MDU1OTk0NTN8MApyPU1hdGgucG93KDIscykK
-cT10PDE/dC9yOnIvdApyZXR1cm4gNTM2ODcwOTExJigocSo5MDA3MTk5MjU0NzQwOTkyfDApKyhxKjM1
-NDIyNDMxODExNzY1MjF8MCkpKjU5OTE5NytzKjEyNTl9LAp6WTpmdW5jdGlvbihhLGIpe3ZhciB0PWEl
-YgppZih0PT09MClyZXR1cm4gMAppZih0PjApcmV0dXJuIHQKaWYoYjwwKXJldHVybiB0LWIKZWxzZSBy
-ZXR1cm4gdCtifSwKd0c6ZnVuY3Rpb24oYSxiKXt2YXIgdAppZihhPjApdD10aGlzLnAzKGEsYikKZWxz
-ZXt0PWI+MzE/MzE6Ygp0PWE+PnQ+Pj4wfXJldHVybiB0fSwKYmY6ZnVuY3Rpb24oYSxiKXtpZihiPDAp
-dGhyb3cgSC5iKEguSShiKSkKcmV0dXJuIHRoaXMucDMoYSxiKX0sCnAzOmZ1bmN0aW9uKGEsYil7cmV0
-dXJuIGI+MzE/MDphPj4+Yn0sCiRpQ1A6MSwKJGlsZjoxfQpKLnVyLnByb3RvdHlwZT17JGlJZjoxfQpK
-LlZBLnByb3RvdHlwZT17fQpKLkRyLnByb3RvdHlwZT17Cm06ZnVuY3Rpb24oYSxiKXtpZihiPDApdGhy
-b3cgSC5iKEguSFkoYSxiKSkKaWYoYj49YS5sZW5ndGgpSC52aChILkhZKGEsYikpCnJldHVybiBhLmNo
-YXJDb2RlQXQoYil9LApXOmZ1bmN0aW9uKGEsYil7aWYoYj49YS5sZW5ndGgpdGhyb3cgSC5iKEguSFko
-YSxiKSkKcmV0dXJuIGEuY2hhckNvZGVBdChiKX0sCmRkOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBI
-Lk5GKGIsYSwwKX0sCmg6ZnVuY3Rpb24oYSxiKXtpZih0eXBlb2YgYiE9InN0cmluZyIpdGhyb3cgSC5i
-KFAuTDMoYixudWxsLG51bGwpKQpyZXR1cm4gYStifSwKVGM6ZnVuY3Rpb24oYSxiKXt2YXIgdD1iLmxl
-bmd0aCxzPWEubGVuZ3RoCmlmKHQ+cylyZXR1cm4hMQpyZXR1cm4gYj09PXRoaXMuRyhhLHMtdCl9LApp
-NzpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdD1QLmpCKGIsYyxhLmxlbmd0aCkscz1hLnN1YnN0cmluZygw
-LGIpLHI9YS5zdWJzdHJpbmcodCkKcmV0dXJuIHMrZCtyfSwKUWk6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0
-CmlmKGM8MHx8Yz5hLmxlbmd0aCl0aHJvdyBILmIoUC5URShjLDAsYS5sZW5ndGgsbnVsbCxudWxsKSkK
-dD1jK2IubGVuZ3RoCmlmKHQ+YS5sZW5ndGgpcmV0dXJuITEKcmV0dXJuIGI9PT1hLnN1YnN0cmluZyhj
-LHQpfSwKbjpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLlFpKGEsYiwwKX0sCk5qOmZ1bmN0aW9uKGEs
-YixjKXtpZihjPT1udWxsKWM9YS5sZW5ndGgKaWYoYjwwKXRocm93IEguYihQLk83KGIsbnVsbCkpCmlm
-KGI+Yyl0aHJvdyBILmIoUC5PNyhiLG51bGwpKQppZihjPmEubGVuZ3RoKXRocm93IEguYihQLk83KGMs
-bnVsbCkpCnJldHVybiBhLnN1YnN0cmluZyhiLGMpfSwKRzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlz
-Lk5qKGEsYixudWxsKX0sCmhjOmZ1bmN0aW9uKGEpe3JldHVybiBhLnRvTG93ZXJDYXNlKCl9LApiUzpm
-dW5jdGlvbihhKXt2YXIgdCxzLHIscT1hLnRyaW0oKSxwPXEubGVuZ3RoCmlmKHA9PT0wKXJldHVybiBx
-CmlmKHRoaXMuVyhxLDApPT09MTMzKXt0PUoubW0ocSwxKQppZih0PT09cClyZXR1cm4iIn1lbHNlIHQ9
-MApzPXAtMQpyPXRoaXMubShxLHMpPT09MTMzP0ouYzEocSxzKTpwCmlmKHQ9PT0wJiZyPT09cClyZXR1
-cm4gcQpyZXR1cm4gcS5zdWJzdHJpbmcodCxyKX0sCkl4OmZ1bmN0aW9uKGEsYil7dmFyIHQscwppZigw
-Pj1iKXJldHVybiIiCmlmKGI9PT0xfHxhLmxlbmd0aD09PTApcmV0dXJuIGEKaWYoYiE9PWI+Pj4wKXRo
-cm93IEguYihDLkVxKQpmb3IodD1hLHM9IiI7ITA7KXtpZigoYiYxKT09PTEpcz10K3MKYj1iPj4+MQpp
-ZihiPT09MClicmVhawp0Kz10fXJldHVybiBzfSwKWFU6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0CmlmKGM8
-MHx8Yz5hLmxlbmd0aCl0aHJvdyBILmIoUC5URShjLDAsYS5sZW5ndGgsbnVsbCxudWxsKSkKdD1hLmlu
-ZGV4T2YoYixjKQpyZXR1cm4gdH0sCk9ZOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuWFUoYSxiLDAp
-fSwKUGs6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMKaWYoYz09bnVsbCljPWEubGVuZ3RoCmVsc2UgaWYo
-YzwwfHxjPmEubGVuZ3RoKXRocm93IEguYihQLlRFKGMsMCxhLmxlbmd0aCxudWxsLG51bGwpKQp0PWIu
-bGVuZ3RoCnM9YS5sZW5ndGgKaWYoYyt0PnMpYz1zLXQKcmV0dXJuIGEubGFzdEluZGV4T2YoYixjKX0s
-CmNuOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuUGsoYSxiLG51bGwpfSwKSXM6ZnVuY3Rpb24oYSxi
-LGMpe3ZhciB0PWEubGVuZ3RoCmlmKGM+dCl0aHJvdyBILmIoUC5URShjLDAsdCxudWxsLG51bGwpKQpy
-ZXR1cm4gSC5tMihhLGIsYyl9LAp0ZzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLklzKGEsYiwwKX0s
-Clo6ZnVuY3Rpb24oYSl7cmV0dXJuIGF9LApnaU86ZnVuY3Rpb24oYSl7dmFyIHQscyxyCmZvcih0PWEu
-bGVuZ3RoLHM9MCxyPTA7cjx0Oysrcil7cz01MzY4NzA5MTEmcythLmNoYXJDb2RlQXQocikKcz01MzY4
-NzA5MTEmcysoKDUyNDI4NyZzKTw8MTApCnNePXM+PjZ9cz01MzY4NzA5MTEmcysoKDY3MTA4ODYzJnMp
-PDwzKQpzXj1zPj4xMQpyZXR1cm4gNTM2ODcwOTExJnMrKCgxNjM4MyZzKTw8MTUpfSwKZ0E6ZnVuY3Rp
-b24oYSl7cmV0dXJuIGEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIpe0guV1koYikKaWYoYj49YS5sZW5n
-dGh8fCExKXRocm93IEguYihILkhZKGEsYikpCnJldHVybiBhW2JdfSwKJGl2WDoxLAokaXFVOjF9Ckgu
-bmQucHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXt2YXIgdD0iTGF0ZUluaXRpYWxpemF0aW9uRXJyb3I6
-ICIrdGhpcy5hCnJldHVybiB0fX0KSC5xai5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4g
-dGhpcy5hLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gQy54Qi5tKHRoaXMuYSxILldZKGIp
-KX19CkguYlEucHJvdG90eXBlPXt9CkguYUwucHJvdG90eXBlPXsKZ2t6OmZ1bmN0aW9uKGEpe3ZhciB0
-PXRoaXMKcmV0dXJuIG5ldyBILmE3KHQsdC5nQSh0KSxILkxoKHQpLkMoImE3PGFMLkU+IikpfSwKelY6
-ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscT10aGlzLHA9cS5nQShxKQppZihiLmxlbmd0aCE9PTApe2lm
-KHA9PT0wKXJldHVybiIiCnQ9SC5kKHEuRSgwLDApKQppZihwIT09cS5nQShxKSl0aHJvdyBILmIoUC5h
-NChxKSkKZm9yKHM9dCxyPTE7cjxwOysrcil7cz1zK2IrSC5kKHEuRSgwLHIpKQppZihwIT09cS5nQShx
-KSl0aHJvdyBILmIoUC5hNChxKSl9cmV0dXJuIHMuY2hhckNvZGVBdCgwKT09MD9zOnN9ZWxzZXtmb3Io
-cj0wLHM9IiI7cjxwOysrcil7cys9SC5kKHEuRSgwLHIpKQppZihwIT09cS5nQShxKSl0aHJvdyBILmIo
-UC5hNChxKSl9cmV0dXJuIHMuY2hhckNvZGVBdCgwKT09MD9zOnN9fSwKZXY6ZnVuY3Rpb24oYSxiKXty
-ZXR1cm4gdGhpcy5HRygwLEguTGgodGhpcykuQygiYTIoYUwuRSkiKS5hKGIpKX0sCkUyOmZ1bmN0aW9u
-KGEsYixjKXt2YXIgdD1ILkxoKHRoaXMpCnJldHVybiBuZXcgSC5sSih0aGlzLHQuS3EoYykuQygiMShh
-TC5FKSIpLmEoYiksdC5DKCJAPGFMLkU+IikuS3EoYykuQygibEo8MSwyPiIpKX19CkgubkgucHJvdG90
-eXBlPXsKZ1VEOmZ1bmN0aW9uKCl7dmFyIHQ9Si5IKHRoaXMuYSkscz10aGlzLmMKaWYocz09bnVsbHx8
-cz50KXJldHVybiB0CnJldHVybiBzfSwKZ0FzOmZ1bmN0aW9uKCl7dmFyIHQ9Si5IKHRoaXMuYSkscz10
-aGlzLmIKaWYocz50KXJldHVybiB0CnJldHVybiBzfSwKZ0E6ZnVuY3Rpb24oYSl7dmFyIHQscz1KLkgo
-dGhpcy5hKSxyPXRoaXMuYgppZihyPj1zKXJldHVybiAwCnQ9dGhpcy5jCmlmKHQ9PW51bGx8fHQ+PXMp
-cmV0dXJuIHMtcgppZih0eXBlb2YgdCE9PSJudW1iZXIiKXJldHVybiB0LkhOKCkKcmV0dXJuIHQtcn0s
-CkU6ZnVuY3Rpb24oYSxiKXt2YXIgdD10aGlzLHM9dC5nQXMoKStiCmlmKGI8MHx8cz49dC5nVUQoKSl0
-aHJvdyBILmIoUC50KGIsdCwiaW5kZXgiLG51bGwsbnVsbCkpCnJldHVybiBKLkdBKHQuYSxzKX0sCnR0
-OmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHE9dGhpcyxwPXEuYixvPXEuYSxuPUouVTYobyksbT1uLmdB
-KG8pLGw9cS5jCmlmKGwhPW51bGwmJmw8bSltPWwKaWYodHlwZW9mIG0hPT0ibnVtYmVyIilyZXR1cm4g
-bS5ITigpCnQ9bS1wCmlmKHQ8PTApe289Si5RaSgwLHEuJHRpLmMpCnJldHVybiBvfXM9UC5POCh0LG4u
-RShvLHApLCExLHEuJHRpLmMpCmZvcihyPTE7cjx0Oysrcil7Qy5ObS5ZKHMscixuLkUobyxwK3IpKQpp
-ZihuLmdBKG8pPG0pdGhyb3cgSC5iKFAuYTQocSkpfXJldHVybiBzfX0KSC5hNy5wcm90b3R5cGU9ewpn
-bDpmdW5jdGlvbigpe3ZhciB0PXRoaXMuZApyZXR1cm4gdH0sCkY6ZnVuY3Rpb24oKXt2YXIgdCxzPXRo
-aXMscj1zLmEscT1KLlU2KHIpLHA9cS5nQShyKQppZihzLmIhPT1wKXRocm93IEguYihQLmE0KHIpKQp0
-PXMuYwppZih0Pj1wKXtzLnNJKG51bGwpCnJldHVybiExfXMuc0kocS5FKHIsdCkpOysrcy5jCnJldHVy
-biEwfSwKc0k6ZnVuY3Rpb24oYSl7dGhpcy5kPXRoaXMuJHRpLmMuYShhKX0sCiRpQW46MX0KSC5pMS5w
-cm90b3R5cGU9ewpna3o6ZnVuY3Rpb24oYSl7dmFyIHQ9SC5MaCh0aGlzKQpyZXR1cm4gbmV3IEguTUgo
-Si5JVCh0aGlzLmEpLHRoaXMuYix0LkMoIkA8MT4iKS5LcSh0LlFbMV0pLkMoIk1IPDEsMj4iKSl9LApn
-QTpmdW5jdGlvbihhKXtyZXR1cm4gSi5IKHRoaXMuYSl9fQpILnh5LnByb3RvdHlwZT17JGliUToxfQpI
-Lk1ILnByb3RvdHlwZT17CkY6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLHM9dC5iCmlmKHMuRigpKXt0LnNJ
-KHQuYy4kMShzLmdsKCkpKQpyZXR1cm4hMH10LnNJKG51bGwpCnJldHVybiExfSwKZ2w6ZnVuY3Rpb24o
-KXt2YXIgdD10aGlzLmEKcmV0dXJuIHR9LApzSTpmdW5jdGlvbihhKXt0aGlzLmE9dGhpcy4kdGkuUVsx
-XS5hKGEpfX0KSC5sSi5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gSi5IKHRoaXMuYSl9
-LApFOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuYi4kMShKLkdBKHRoaXMuYSxiKSl9fQpILlU1LnBy
-b3RvdHlwZT17CmdrejpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEgudkcoSi5JVCh0aGlzLmEpLHRoaXMu
-Yix0aGlzLiR0aS5DKCJ2RzwxPiIpKX19CkgudkcucHJvdG90eXBlPXsKRjpmdW5jdGlvbigpe3ZhciB0
-LHMKZm9yKHQ9dGhpcy5hLHM9dGhpcy5iO3QuRigpOylpZihILm9UKHMuJDEodC5nbCgpKSkpcmV0dXJu
-ITAKcmV0dXJuITF9LApnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmEuZ2woKX19CkguU1UucHJvdG90
-eXBlPXt9CkguUmUucHJvdG90eXBlPXsKWTpmdW5jdGlvbihhLGIsYyl7SC5MaCh0aGlzKS5DKCJSZS5F
-IikuYShjKQp0aHJvdyBILmIoUC5MNCgiQ2Fubm90IG1vZGlmeSBhbiB1bm1vZGlmaWFibGUgbGlzdCIp
-KX19CkgudzIucHJvdG90eXBlPXt9Ckgud3YucHJvdG90eXBlPXsKZ2lPOmZ1bmN0aW9uKGEpe3ZhciB0
-PXRoaXMuX2hhc2hDb2RlCmlmKHQhPW51bGwpcmV0dXJuIHQKdD01MzY4NzA5MTEmNjY0NTk3KkouaGYo
-dGhpcy5hKQp0aGlzLl9oYXNoQ29kZT10CnJldHVybiB0fSwKWjpmdW5jdGlvbihhKXtyZXR1cm4nU3lt
-Ym9sKCInK0guZCh0aGlzLmEpKyciKSd9LApETjpmdW5jdGlvbihhLGIpe2lmKGI9PW51bGwpcmV0dXJu
-ITEKcmV0dXJuIGIgaW5zdGFuY2VvZiBILnd2JiZ0aGlzLmE9PWIuYX0sCiRpR0Q6MX0KSC5QRC5wcm90
-b3R5cGU9e30KSC5XVS5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3JldHVybiBQLm5PKHRoaXMpfSwK
-WTpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9SC5MaCh0aGlzKQp0LmMuYShiKQp0LlFbMV0uYShjKQpILmRj
-KCl9LApnUHU6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMucTQoYSxILkxoKHRoaXMpLkMoIk4zPDEsMj4i
-KSl9LApxNDpmdW5jdGlvbihhLGIpe3ZhciB0PXRoaXMKcmV0dXJuIFAubDAoZnVuY3Rpb24oKXt2YXIg
-cz1hCnZhciByPTAscT0xLHAsbyxuLG0sbApyZXR1cm4gZnVuY3Rpb24gJGFzeW5jJGdQdShjLGQpe2lm
-KGM9PT0xKXtwPWQKcj1xfXdoaWxlKHRydWUpc3dpdGNoKHIpe2Nhc2UgMDpvPXQuZ1YoKSxvPW8uZ2t6
-KG8pLG49SC5MaCh0KSxuPW4uQygiQDwxPiIpLktxKG4uUVsxXSkuQygiTjM8MSwyPiIpCmNhc2UgMjpp
-Zighby5GKCkpe3I9MwpicmVha31tPW8uZ2woKQpsPXQucSgwLG0pCmwudG9TdHJpbmcKcj00CnJldHVy
-biBuZXcgUC5OMyhtLGwsbikKY2FzZSA0OnI9MgpicmVhawpjYXNlIDM6cmV0dXJuIFAuVGgoKQpjYXNl
-IDE6cmV0dXJuIFAuWW0ocCl9fX0sYil9LAokaVowOjF9CkguTFAucHJvdG90eXBlPXsKZ0E6ZnVuY3Rp
-b24oYSl7cmV0dXJuIHRoaXMuYX0sCng0OmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhIT0ic3RyaW5nIily
-ZXR1cm4hMQppZigiX19wcm90b19fIj09PWEpcmV0dXJuITEKcmV0dXJuIHRoaXMuYi5oYXNPd25Qcm9w
-ZXJ0eShhKX0sCnE6ZnVuY3Rpb24oYSxiKXtpZighdGhpcy54NChiKSlyZXR1cm4gbnVsbApyZXR1cm4g
-dGhpcy5EKGIpfSwKRDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5iW0guYyhhKV19LApLOmZ1bmN0aW9u
-KGEsYil7dmFyIHQscyxyLHEscD1ILkxoKHRoaXMpCnAuQygifigxLDIpIikuYShiKQp0PXRoaXMuYwpm
-b3Iocz10Lmxlbmd0aCxwPXAuUVsxXSxyPTA7cjxzOysrcil7cT10W3JdCmIuJDIocSxwLmEodGhpcy5E
-KHEpKSl9fSwKZ1Y6ZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEguWFIodGhpcyxILkxoKHRoaXMpLkMoIlhS
-PDE+IikpfX0KSC5YUi5wcm90b3R5cGU9ewpna3o6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hLmMKcmV0
-dXJuIG5ldyBKLm0xKHQsdC5sZW5ndGgsSC50Nih0KS5DKCJtMTwxPiIpKX0sCmdBOmZ1bmN0aW9uKGEp
-e3JldHVybiB0aGlzLmEuYy5sZW5ndGh9fQpILkxJLnByb3RvdHlwZT17CmdXYTpmdW5jdGlvbigpe3Zh
-ciB0PXRoaXMuYQpyZXR1cm4gdH0sCmduZDpmdW5jdGlvbigpe3ZhciB0LHMscixxLHA9dGhpcwppZihw
-LmM9PT0xKXJldHVybiBDLmRuCnQ9cC5kCnM9dC5sZW5ndGgtcC5lLmxlbmd0aC1wLmYKaWYocz09PTAp
-cmV0dXJuIEMuZG4Kcj1bXQpmb3IocT0wO3E8czsrK3Epe2lmKHE+PXQubGVuZ3RoKXJldHVybiBILmso
-dCxxKQpyLnB1c2godFtxXSl9cmV0dXJuIEoudW4ocil9LApnVm06ZnVuY3Rpb24oKXt2YXIgdCxzLHIs
-cSxwLG8sbixtLGw9dGhpcwppZihsLmMhPT0wKXJldHVybiBDLkR4CnQ9bC5lCnM9dC5sZW5ndGgKcj1s
-LmQKcT1yLmxlbmd0aC1zLWwuZgppZihzPT09MClyZXR1cm4gQy5EeApwPW5ldyBILk41KHUuZW8pCmZv
-cihvPTA7bzxzOysrbyl7aWYobz49dC5sZW5ndGgpcmV0dXJuIEguayh0LG8pCm49dFtvXQptPXErbwpp
-ZihtPDB8fG0+PXIubGVuZ3RoKXJldHVybiBILmsocixtKQpwLlkoMCxuZXcgSC53dihuKSxyW21dKX1y
-ZXR1cm4gbmV3IEguUEQocCx1LmdGKX0sCiRpdlE6MX0KSC5Dai5wcm90b3R5cGU9ewokMjpmdW5jdGlv
-bihhLGIpe3ZhciB0CkguYyhhKQp0PXRoaXMuYQp0LmI9dC5iKyIkIitILmQoYSkKQy5ObS5pKHRoaXMu
-YixhKQpDLk5tLmkodGhpcy5jLGIpOysrdC5hfSwKJFM6MTN9CkguZjkucHJvdG90eXBlPXsKcVM6ZnVu
-Y3Rpb24oYSl7dmFyIHQscyxyPXRoaXMscT1uZXcgUmVnRXhwKHIuYSkuZXhlYyhhKQppZihxPT1udWxs
-KXJldHVybiBudWxsCnQ9T2JqZWN0LmNyZWF0ZShudWxsKQpzPXIuYgppZihzIT09LTEpdC5hcmd1bWVu
-dHM9cVtzKzFdCnM9ci5jCmlmKHMhPT0tMSl0LmFyZ3VtZW50c0V4cHI9cVtzKzFdCnM9ci5kCmlmKHMh
-PT0tMSl0LmV4cHI9cVtzKzFdCnM9ci5lCmlmKHMhPT0tMSl0Lm1ldGhvZD1xW3MrMV0Kcz1yLmYKaWYo
-cyE9PS0xKXQucmVjZWl2ZXI9cVtzKzFdCnJldHVybiB0fX0KSC5XMC5wcm90b3R5cGU9ewpaOmZ1bmN0
-aW9uKGEpe3ZhciB0PXRoaXMuYgppZih0PT1udWxsKXJldHVybiJOb1N1Y2hNZXRob2RFcnJvcjogIitI
-LmQodGhpcy5hKQpyZXR1cm4iTm9TdWNoTWV0aG9kRXJyb3I6IG1ldGhvZCBub3QgZm91bmQ6ICciK3Qr
-Iicgb24gbnVsbCJ9fQpILmF6LnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzLHI9
-Ik5vU3VjaE1ldGhvZEVycm9yOiBtZXRob2Qgbm90IGZvdW5kOiAnIixxPXMuYgppZihxPT1udWxsKXJl
-dHVybiJOb1N1Y2hNZXRob2RFcnJvcjogIitILmQocy5hKQp0PXMuYwppZih0PT1udWxsKXJldHVybiBy
-K3ErIicgKCIrSC5kKHMuYSkrIikiCnJldHVybiByK3ErIicgb24gJyIrdCsiJyAoIitILmQocy5hKSsi
-KSJ9fQpILnZWLnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCnJldHVybiB0Lmxl
-bmd0aD09PTA/IkVycm9yIjoiRXJyb3I6ICIrdH19CkguYnEucHJvdG90eXBlPXt9CkguQW0ucHJvdG90
-eXBlPXsKJDE6ZnVuY3Rpb24oYSl7aWYodS5XLmIoYSkpaWYoYS4kdGhyb3duSnNFcnJvcj09bnVsbClh
-LiR0aHJvd25Kc0Vycm9yPXRoaXMuYQpyZXR1cm4gYX0sCiRTOjZ9CkguWE8ucHJvdG90eXBlPXsKWjpm
-dW5jdGlvbihhKXt2YXIgdCxzPXRoaXMuYgppZihzIT1udWxsKXJldHVybiBzCnM9dGhpcy5hCnQ9cyE9
-PW51bGwmJnR5cGVvZiBzPT09Im9iamVjdCI/cy5zdGFjazpudWxsCnJldHVybiB0aGlzLmI9dD09bnVs
-bD8iIjp0fSwKJGlHejoxfQpILlRwLnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5j
-b25zdHJ1Y3RvcixzPXQ9PW51bGw/bnVsbDp0Lm5hbWUKcmV0dXJuIkNsb3N1cmUgJyIrSC5OUShzPT1u
-dWxsPyJ1bmtub3duIjpzKSsiJyJ9LAokaUVIOjEsCmdRbDpmdW5jdGlvbigpe3JldHVybiB0aGlzfSwK
-JEM6IiQxIiwKJFI6MSwKJEQ6bnVsbH0KSC5sYy5wcm90b3R5cGU9e30KSC56eC5wcm90b3R5cGU9ewpa
-OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuJHN0YXRpY19uYW1lCmlmKHQ9PW51bGwpcmV0dXJuIkNsb3N1
-cmUgb2YgdW5rbm93biBzdGF0aWMgbWV0aG9kIgpyZXR1cm4iQ2xvc3VyZSAnIitILk5RKHQpKyInIn19
-CkguankucHJvdG90eXBlPXsKRE46ZnVuY3Rpb24oYSxiKXt2YXIgdD10aGlzCmlmKGI9PW51bGwpcmV0
-dXJuITEKaWYodD09PWIpcmV0dXJuITAKaWYoIShiIGluc3RhbmNlb2YgSC5qeSkpcmV0dXJuITEKcmV0
-dXJuIHQuYT09PWIuYSYmdC5iPT09Yi5iJiZ0LmM9PT1iLmN9LApnaU86ZnVuY3Rpb24oYSl7dmFyIHQs
-cz10aGlzLmMKaWYocz09bnVsbCl0PUguZVEodGhpcy5hKQplbHNlIHQ9dHlwZW9mIHMhPT0ib2JqZWN0
-Ij9KLmhmKHMpOkguZVEocykKcmV0dXJuKHReSC5lUSh0aGlzLmIpKT4+PjB9LApaOmZ1bmN0aW9uKGEp
-e3ZhciB0PXRoaXMuYwppZih0PT1udWxsKXQ9dGhpcy5hCnJldHVybiJDbG9zdXJlICciK0guZCh0aGlz
-LmQpKyInIG9mICIrKCJJbnN0YW5jZSBvZiAnIitILmQoSC5saCh0KSkrIiciKX19CkguRXEucHJvdG90
-eXBlPXsKWjpmdW5jdGlvbihhKXtyZXR1cm4iUnVudGltZUVycm9yOiAiK0guZCh0aGlzLmEpfX0KSC5r
-WS5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3JldHVybiJBc3NlcnRpb24gZmFpbGVkOiAiK1AuaCh0
-aGlzLmEpfX0KSC5ONS5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hfSwKZ1Y6
-ZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEguaTUodGhpcyxILkxoKHRoaXMpLkMoImk1PDE+IikpfSwKeDQ6
-ZnVuY3Rpb24oYSl7dmFyIHQscwppZih0eXBlb2YgYT09InN0cmluZyIpe3Q9dGhpcy5iCmlmKHQ9PW51
-bGwpcmV0dXJuITEKcmV0dXJuIHRoaXMuWHUodCxhKX1lbHNle3M9dGhpcy5DWChhKQpyZXR1cm4gc319
-LApDWDpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmQKaWYodD09bnVsbClyZXR1cm4hMQpyZXR1cm4gdGhp
-cy5GaCh0aGlzLkJ0KHQsSi5oZihhKSYweDNmZmZmZmYpLGEpPj0wfSwKcTpmdW5jdGlvbihhLGIpe3Zh
-ciB0LHMscixxLHA9dGhpcyxvPW51bGwKaWYodHlwZW9mIGI9PSJzdHJpbmciKXt0PXAuYgppZih0PT1u
-dWxsKXJldHVybiBvCnM9cC5qMih0LGIpCnI9cz09bnVsbD9vOnMuYgpyZXR1cm4gcn1lbHNlIGlmKHR5
-cGVvZiBiPT0ibnVtYmVyIiYmKGImMHgzZmZmZmZmKT09PWIpe3E9cC5jCmlmKHE9PW51bGwpcmV0dXJu
-IG8Kcz1wLmoyKHEsYikKcj1zPT1udWxsP286cy5iCnJldHVybiByfWVsc2UgcmV0dXJuIHAuYWEoYil9
-LAphYTpmdW5jdGlvbihhKXt2YXIgdCxzLHI9dGhpcy5kCmlmKHI9PW51bGwpcmV0dXJuIG51bGwKdD10
-aGlzLkJ0KHIsSi5oZihhKSYweDNmZmZmZmYpCnM9dGhpcy5GaCh0LGEpCmlmKHM8MClyZXR1cm4gbnVs
-bApyZXR1cm4gdFtzXS5ifSwKWTpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEscCxvLG49dGhpcyxt
-PUguTGgobikKbS5jLmEoYikKbS5RWzFdLmEoYykKaWYodHlwZW9mIGI9PSJzdHJpbmciKXt0PW4uYgpu
-LkVIKHQ9PW51bGw/bi5iPW4ueksoKTp0LGIsYyl9ZWxzZSBpZih0eXBlb2YgYj09Im51bWJlciImJihi
-JjB4M2ZmZmZmZik9PT1iKXtzPW4uYwpuLkVIKHM9PW51bGw/bi5jPW4ueksoKTpzLGIsYyl9ZWxzZXty
-PW4uZAppZihyPT1udWxsKXI9bi5kPW4ueksoKQpxPUouaGYoYikmMHgzZmZmZmZmCnA9bi5CdChyLHEp
-CmlmKHA9PW51bGwpbi5FSShyLHEsW24uSG4oYixjKV0pCmVsc2V7bz1uLkZoKHAsYikKaWYobz49MClw
-W29dLmI9YwplbHNlIHAucHVzaChuLkhuKGIsYykpfX19LApLOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxy
-PXRoaXMKSC5MaChyKS5DKCJ+KDEsMikiKS5hKGIpCnQ9ci5lCnM9ci5yCmZvcig7dCE9bnVsbDspe2Iu
-JDIodC5hLHQuYikKaWYocyE9PXIucil0aHJvdyBILmIoUC5hNChyKSkKdD10LmN9fSwKRUg6ZnVuY3Rp
-b24oYSxiLGMpe3ZhciB0LHM9dGhpcyxyPUguTGgocykKci5jLmEoYikKci5RWzFdLmEoYykKdD1zLmoy
-KGEsYikKaWYodD09bnVsbClzLkVJKGEsYixzLkhuKGIsYykpCmVsc2UgdC5iPWN9LAprczpmdW5jdGlv
-bigpe3RoaXMucj10aGlzLnIrMSY2NzEwODg2M30sCkhuOmZ1bmN0aW9uKGEsYil7dmFyIHQ9dGhpcyxz
-PUguTGgodCkscj1uZXcgSC5kYihzLmMuYShhKSxzLlFbMV0uYShiKSkKaWYodC5lPT1udWxsKXQuZT10
-LmY9cgplbHNle3M9dC5mCnMudG9TdHJpbmcKci5kPXMKdC5mPXMuYz1yfSsrdC5hCnQua3MoKQpyZXR1
-cm4gcn0sCkZoOmZ1bmN0aW9uKGEsYil7dmFyIHQscwppZihhPT1udWxsKXJldHVybi0xCnQ9YS5sZW5n
-dGgKZm9yKHM9MDtzPHQ7KytzKWlmKEouUk0oYVtzXS5hLGIpKXJldHVybiBzCnJldHVybi0xfSwKWjpm
-dW5jdGlvbihhKXtyZXR1cm4gUC5uTyh0aGlzKX0sCmoyOmZ1bmN0aW9uKGEsYil7cmV0dXJuIGFbYl19
-LApCdDpmdW5jdGlvbihhLGIpe3JldHVybiBhW2JdfSwKRUk6ZnVuY3Rpb24oYSxiLGMpe2FbYl09Y30s
-CnJuOmZ1bmN0aW9uKGEsYil7ZGVsZXRlIGFbYl19LApYdTpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlz
-LmoyKGEsYikhPW51bGx9LAp6SzpmdW5jdGlvbigpe3ZhciB0PSI8bm9uLWlkZW50aWZpZXIta2V5PiIs
-cz1PYmplY3QuY3JlYXRlKG51bGwpCnRoaXMuRUkocyx0LHMpCnRoaXMucm4ocyx0KQpyZXR1cm4gc30s
-CiRpRm86MX0KSC5kYi5wcm90b3R5cGU9e30KSC5pNS5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXty
-ZXR1cm4gdGhpcy5hLmF9LApna3o6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hLHM9bmV3IEguTjYodCx0
-LnIsdGhpcy4kdGkuQygiTjY8MT4iKSkKcy5jPXQuZQpyZXR1cm4gc30sCnRnOmZ1bmN0aW9uKGEsYil7
-cmV0dXJuIHRoaXMuYS54NChiKX19CkguTjYucHJvdG90eXBlPXsKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4g
-dGhpcy5kfSwKRjpmdW5jdGlvbigpe3ZhciB0LHM9dGhpcyxyPXMuYQppZihzLmIhPT1yLnIpdGhyb3cg
-SC5iKFAuYTQocikpCnQ9cy5jCmlmKHQ9PW51bGwpe3Muc3FZKG51bGwpCnJldHVybiExfWVsc2V7cy5z
-cVkodC5hKQpzLmM9dC5jCnJldHVybiEwfX0sCnNxWTpmdW5jdGlvbihhKXt0aGlzLmQ9dGhpcy4kdGku
-Yy5hKGEpfSwKJGlBbjoxfQpILnIucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMu
-YShhKX0sCiRTOjZ9CkguZEMucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5h
-KGEsYil9LAokUzoyNn0KSC53Ti5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5h
-KEguYyhhKSl9LAokUzoyMX0KSC5WUi5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3JldHVybiJSZWdF
-eHAvIit0aGlzLmErIi8iK3RoaXMuYi5mbGFnc30sCmdIYzpmdW5jdGlvbigpe3ZhciB0PXRoaXMscz10
-LmMKaWYocyE9bnVsbClyZXR1cm4gcwpzPXQuYgpyZXR1cm4gdC5jPUgudjQodC5hLHMubXVsdGlsaW5l
-LCFzLmlnbm9yZUNhc2Uscy51bmljb2RlLHMuZG90QWxsLCEwKX0sCmRkOmZ1bmN0aW9uKGEsYil7cmV0
-dXJuIG5ldyBILktXKHRoaXMsYiwwKX0sClVaOmZ1bmN0aW9uKGEsYil7dmFyIHQscz10aGlzLmdIYygp
-CnMubGFzdEluZGV4PWIKdD1zLmV4ZWMoYSkKaWYodD09bnVsbClyZXR1cm4gbnVsbApyZXR1cm4gbmV3
-IEguRUsodCl9LAokaXZYOjEsCiRpd0w6MX0KSC5FSy5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7
-dmFyIHQKSC5XWShiKQp0PXRoaXMuYgppZihiPj10Lmxlbmd0aClyZXR1cm4gSC5rKHQsYikKcmV0dXJu
-IHRbYl19LAokaU9kOjEsCiRpaWI6MX0KSC5LVy5wcm90b3R5cGU9ewpna3o6ZnVuY3Rpb24oYSl7cmV0
-dXJuIG5ldyBILlBiKHRoaXMuYSx0aGlzLmIsdGhpcy5jKX19CkguUGIucHJvdG90eXBlPXsKZ2w6ZnVu
-Y3Rpb24oKXt2YXIgdD10aGlzLmQKdC50b1N0cmluZwpyZXR1cm4gdH0sCkY6ZnVuY3Rpb24oKXt2YXIg
-dCxzLHIscSxwLG8sbj10aGlzLG09bi5iCmlmKG09PW51bGwpcmV0dXJuITEKdD1uLmMKcz1tLmxlbmd0
-aAppZih0PD1zKXtyPW4uYQpxPXIuVVoobSx0KQppZihxIT1udWxsKXtuLmQ9cQp0PXEuYgpwPXQuaW5k
-ZXgKbz1wK3RbMF0ubGVuZ3RoCmlmKHA9PT1vKXtpZihyLmIudW5pY29kZSl7dD1uLmMKcj10KzEKaWYo
-cjxzKXt0PUMueEIubShtLHQpCmlmKHQ+PTU1Mjk2JiZ0PD01NjMxOSl7dD1DLnhCLm0obSxyKQp0PXQ+
-PTU2MzIwJiZ0PD01NzM0M31lbHNlIHQ9ITF9ZWxzZSB0PSExfWVsc2UgdD0hMQpvPSh0P28rMTpvKSsx
-fW4uYz1vCnJldHVybiEwfX1uLmI9bi5kPW51bGwKcmV0dXJuITF9LAokaUFuOjF9CkgudFEucHJvdG90
-eXBlPXsKcTpmdW5jdGlvbihhLGIpe0guV1koYikKaWYoYiE9PTApSC52aChQLk83KGIsbnVsbCkpCnJl
-dHVybiB0aGlzLmN9LAokaU9kOjF9CkguTkYucHJvdG90eXBlPXsKZ2t6OmZ1bmN0aW9uKGEpe3JldHVy
-biBuZXcgSC5TZCh0aGlzLmEsdGhpcy5iLHRoaXMuYyl9fQpILlNkLnByb3RvdHlwZT17CkY6ZnVuY3Rp
-b24oKXt2YXIgdCxzLHI9dGhpcyxxPXIuYyxwPXIuYixvPXAubGVuZ3RoLG49ci5hLG09bi5sZW5ndGgK
-aWYocStvPm0pe3IuZD1udWxsCnJldHVybiExfXQ9bi5pbmRleE9mKHAscSkKaWYodDwwKXtyLmM9bSsx
-CnIuZD1udWxsCnJldHVybiExfXM9dCtvCnIuZD1uZXcgSC50USh0LHApCnIuYz1zPT09ci5jP3MrMTpz
-CnJldHVybiEwfSwKZ2w6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLmQKdC50b1N0cmluZwpyZXR1cm4gdH0s
-CiRpQW46MX0KSC5wRi5wcm90b3R5cGU9eyRpcEY6MSwkaUFTOjF9CkguYjAucHJvdG90eXBlPXsKZ0E6
-ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwKJGlYajoxfQpILkRnLnByb3RvdHlwZT17CnE6ZnVu
-Y3Rpb24oYSxiKXtILldZKGIpCkgub2QoYixhLGEubGVuZ3RoKQpyZXR1cm4gYVtiXX0sClk6ZnVuY3Rp
-b24oYSxiLGMpe0guZGooYykKSC5vZChiLGEsYS5sZW5ndGgpCmFbYl09Y30sCiRpYlE6MSwKJGljWDox
-LAokaXpNOjF9CkguUGcucHJvdG90eXBlPXsKWTpmdW5jdGlvbihhLGIsYyl7SC5XWShjKQpILm9kKGIs
-YSxhLmxlbmd0aCkKYVtiXT1jfSwKJGliUToxLAokaWNYOjEsCiRpek06MX0KSC54ai5wcm90b3R5cGU9
-ewpxOmZ1bmN0aW9uKGEsYil7SC5XWShiKQpILm9kKGIsYSxhLmxlbmd0aCkKcmV0dXJuIGFbYl19fQpI
-LmRFLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtILldZKGIpCkgub2QoYixhLGEubGVuZ3RoKQpy
-ZXR1cm4gYVtiXX19CkguWkEucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe0guV1koYikKSC5vZChi
-LGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfX0KSC53Zi5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7
-SC5XWShiKQpILm9kKGIsYSxhLmxlbmd0aCkKcmV0dXJuIGFbYl19fQpILlBxLnByb3RvdHlwZT17CnE6
-ZnVuY3Rpb24oYSxiKXtILldZKGIpCkgub2QoYixhLGEubGVuZ3RoKQpyZXR1cm4gYVtiXX19CkguZUUu
-cHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIp
-e0guV1koYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfX0KSC5WNi5wcm90b3R5cGU9ewpn
-QTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9LApxOmZ1bmN0aW9uKGEsYil7SC5XWShiKQpILm9k
-KGIsYSxhLmxlbmd0aCkKcmV0dXJuIGFbYl19LAokaVY2OjEsCiRpbjY6MX0KSC5SRy5wcm90b3R5cGU9
-e30KSC5WUC5wcm90b3R5cGU9e30KSC5XQi5wcm90b3R5cGU9e30KSC5aRy5wcm90b3R5cGU9e30KSC5K
-Yy5wcm90b3R5cGU9ewpDOmZ1bmN0aW9uKGEpe3JldHVybiBILmNFKHYudHlwZVVuaXZlcnNlLHRoaXMs
-YSl9LApLcTpmdW5jdGlvbihhKXtyZXR1cm4gSC52NSh2LnR5cGVVbml2ZXJzZSx0aGlzLGEpfX0KSC5F
-VC5wcm90b3R5cGU9e30KSC51OS5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmF9
-fQpILngucHJvdG90eXBlPXt9ClAudGgucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhp
-cy5hLHM9dC5hCnQuYT1udWxsCnMuJDAoKX0sCiRTOjEyfQpQLmhhLnByb3RvdHlwZT17CiQxOmZ1bmN0
-aW9uKGEpe3ZhciB0LHMKdGhpcy5hLmE9dS5NLmEoYSkKdD10aGlzLmIKcz10aGlzLmMKdC5maXJzdENo
-aWxkP3QucmVtb3ZlQ2hpbGQocyk6dC5hcHBlbmRDaGlsZChzKX0sCiRTOjQ1fQpQLlZzLnByb3RvdHlw
-ZT17CiQwOmZ1bmN0aW9uKCl7dGhpcy5hLiQwKCl9LAokQzoiJDAiLAokUjowLAokUzowfQpQLkZ0LnBy
-b3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7dGhpcy5hLiQwKCl9LAokQzoiJDAiLAokUjowLAokUzowfQpQ
-LlczLnByb3RvdHlwZT17CkNZOmZ1bmN0aW9uKGEsYil7aWYoc2VsZi5zZXRUaW1lb3V0IT1udWxsKXNl
-bGYuc2V0VGltZW91dChILnRSKG5ldyBQLnlIKHRoaXMsYiksMCksYSkKZWxzZSB0aHJvdyBILmIoUC5M
-NCgiYHNldFRpbWVvdXQoKWAgbm90IGZvdW5kLiIpKX19ClAueUgucHJvdG90eXBlPXsKJDA6ZnVuY3Rp
-b24oKXt0aGlzLmIuJDAoKX0sCiRDOiIkMCIsCiRSOjAsCiRTOjF9ClAuaWgucHJvdG90eXBlPXsKYU06
-ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9dGhpcy4kdGkKci5DKCIxLyIpLmEoYikKdD0hdGhpcy5ifHxy
-LkMoImI4PDE+IikuYihiKQpzPXRoaXMuYQppZih0KXMuWGYoYikKZWxzZSBzLlgyKHIuYy5hKGIpKX0s
-CncwOmZ1bmN0aW9uKGEsYil7dmFyIHQKaWYoYj09bnVsbCliPVAudjAoYSkKdD10aGlzLmEKaWYodGhp
-cy5iKXQuWkwoYSxiKQplbHNlIHQuTmsoYSxiKX19ClAuV00ucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24o
-YSl7cmV0dXJuIHRoaXMuYS4kMigwLGEpfSwKJFM6Mjd9ClAuU1gucHJvdG90eXBlPXsKJDI6ZnVuY3Rp
-b24oYSxiKXt0aGlzLmEuJDIoMSxuZXcgSC5icShhLHUubC5hKGIpKSl9LAokQzoiJDIiLAokUjoyLAok
-UzoyOX0KUC5Hcy5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3RoaXMuYShILldZKGEpLGIpfSwK
-JFM6MzB9ClAuRnkucHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXtyZXR1cm4iSXRlcmF0aW9uTWFya2Vy
-KCIrdGhpcy5iKyIsICIrSC5kKHRoaXMuYSkrIikifX0KUC5HVi5wcm90b3R5cGU9ewpnbDpmdW5jdGlv
-bigpe3ZhciB0PXRoaXMuYyxzPXQhPW51bGw/dC5nbCgpOnRoaXMuYgpyZXR1cm4gdGhpcy4kdGkuYy5h
-KHMpfSwKRjpmdW5jdGlvbigpe3ZhciB0LHMscixxLHAsbz10aGlzCmZvcig7ITA7KXt0PW8uYwppZih0
-IT1udWxsKWlmKHQuRigpKXJldHVybiEwCmVsc2Ugby5jPW51bGwKcz1mdW5jdGlvbihhLGIsYyl7dmFy
-IG4sbT1iCndoaWxlKHRydWUpdHJ5e3JldHVybiBhKG0sbil9Y2F0Y2gobCl7bj1sCm09Y319KG8uYSww
-LDEpCmlmKHMgaW5zdGFuY2VvZiBQLkZ5KXtyPXMuYgppZihyPT09Mil7cT1vLmQKaWYocT09bnVsbHx8
-cS5sZW5ndGg9PT0wKXtvLnNFQyhudWxsKQpyZXR1cm4hMX1pZigwPj1xLmxlbmd0aClyZXR1cm4gSC5r
-KHEsLTEpCm8uYT1xLnBvcCgpCmNvbnRpbnVlfWVsc2V7dD1zLmEKaWYocj09PTMpdGhyb3cgdAplbHNl
-e3A9Si5JVCh0KQppZihwIGluc3RhbmNlb2YgUC5HVil7dD1vLmQKaWYodD09bnVsbCl0PW8uZD1bXQpD
-Lk5tLmkodCxvLmEpCm8uYT1wLmEKY29udGludWV9ZWxzZXtvLmM9cApjb250aW51ZX19fX1lbHNle28u
-c0VDKHMpCnJldHVybiEwfX1yZXR1cm4hMX0sCnNFQzpmdW5jdGlvbihhKXt0aGlzLmI9dGhpcy4kdGku
-Yy5hKGEpfSwKJGlBbjoxfQpQLnE0LnByb3RvdHlwZT17CmdrejpmdW5jdGlvbihhKXtyZXR1cm4gbmV3
-IFAuR1YodGhpcy5hKCksdGhpcy4kdGkuQygiR1Y8MT4iKSl9fQpQLmI4LnByb3RvdHlwZT17fQpQLlBm
-LnByb3RvdHlwZT17CncwOmZ1bmN0aW9uKGEsYil7dmFyIHQKUC5VSShhLCJlcnJvciIsdS5LKQp0PXRo
-aXMuYQppZih0LmEhPT0wKXRocm93IEguYihQLlBWKCJGdXR1cmUgYWxyZWFkeSBjb21wbGV0ZWQiKSkK
-aWYoYj09bnVsbCliPVAudjAoYSkKdC5OayhhLGIpfSwKcG06ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMu
-dzAoYSxudWxsKX19ClAuWmYucHJvdG90eXBlPXsKYU06ZnVuY3Rpb24oYSxiKXt2YXIgdAp0aGlzLiR0
-aS5DKCIxLyIpLmEoYikKdD10aGlzLmEKaWYodC5hIT09MCl0aHJvdyBILmIoUC5QVigiRnV0dXJlIGFs
-cmVhZHkgY29tcGxldGVkIikpCnQuWGYoYil9fQpQLkZlLnByb3RvdHlwZT17CkhSOmZ1bmN0aW9uKGEp
-e2lmKCh0aGlzLmMmMTUpIT09NilyZXR1cm4hMApyZXR1cm4gdGhpcy5iLmIuYnYodS5tLmEodGhpcy5k
-KSxhLmEsdS55LHUuSyl9LApLdzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmUscz11Lnoscj11LksscT10
-aGlzLiR0aS5DKCIyLyIpLHA9dGhpcy5iLmIKaWYodS5hZy5iKHQpKXJldHVybiBxLmEocC5ycCh0LGEu
-YSxhLmIscyxyLHUubCkpCmVsc2UgcmV0dXJuIHEuYShwLmJ2KHUuYkkuYSh0KSxhLmEscyxyKSl9fQpQ
-LnZzLnByb3RvdHlwZT17ClNxOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscT10aGlzLiR0aQpxLktx
-KGMpLkMoIjEvKDIpIikuYShhKQp0PSQuWDMKaWYodCE9PUMuTlUpe2MuQygiQDwwLz4iKS5LcShxLmMp
-LkMoIjEoMikiKS5hKGEpCmlmKGIhPW51bGwpYj1QLlZIKGIsdCl9cz1uZXcgUC52cygkLlgzLGMuQygi
-dnM8MD4iKSkKcj1iPT1udWxsPzE6Mwp0aGlzLnhmKG5ldyBQLkZlKHMscixhLGIscS5DKCJAPDE+Iiku
-S3EoYykuQygiRmU8MSwyPiIpKSkKcmV0dXJuIHN9LApXNzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlz
-LlNxKGEsbnVsbCxiKX0sClFkOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzPXRoaXMuJHRpCnMuS3EoYyku
-QygiMS8oMikiKS5hKGEpCnQ9bmV3IFAudnMoJC5YMyxjLkMoInZzPDA+IikpCnRoaXMueGYobmV3IFAu
-RmUodCwxOSxhLGIscy5DKCJAPDE+IikuS3EoYykuQygiRmU8MSwyPiIpKSkKcmV0dXJuIHR9LApPQTpm
-dW5jdGlvbihhKXt2YXIgdCxzLHIKdS5tLmEobnVsbCkKdD10aGlzLiR0aQpzPSQuWDMKcj1uZXcgUC52
-cyhzLHQpCmlmKHMhPT1DLk5VKWE9UC5WSChhLHMpCnRoaXMueGYobmV3IFAuRmUociwyLG51bGwsYSx0
-LkMoIkA8MT4iKS5LcSh0LmMpLkMoIkZlPDEsMj4iKSkpCnJldHVybiByfSwKeGY6ZnVuY3Rpb24oYSl7
-dmFyIHQscz10aGlzLHI9cy5hCmlmKHI8PTEpe2EuYT11LnguYShzLmMpCnMuYz1hfWVsc2V7aWYocj09
-PTIpe3Q9dS5fLmEocy5jKQpyPXQuYQppZihyPDQpe3QueGYoYSkKcmV0dXJufXMuYT1yCnMuYz10LmN9
-UC5UayhudWxsLG51bGwscy5iLHUuTS5hKG5ldyBQLmRhKHMsYSkpKX19LApqUTpmdW5jdGlvbihhKXt2
-YXIgdCxzLHIscSxwLG8sbj10aGlzLG09e30KbS5hPWEKaWYoYT09bnVsbClyZXR1cm4KdD1uLmEKaWYo
-dDw9MSl7cz11LnguYShuLmMpCm4uYz1hCmlmKHMhPW51bGwpe3I9YS5hCmZvcihxPWE7ciE9bnVsbDtx
-PXIscj1wKXA9ci5hCnEuYT1zfX1lbHNle2lmKHQ9PT0yKXtvPXUuXy5hKG4uYykKdD1vLmEKaWYodDw0
-KXtvLmpRKGEpCnJldHVybn1uLmE9dApuLmM9by5jfW0uYT1uLk44KGEpClAuVGsobnVsbCxudWxsLG4u
-Yix1Lk0uYShuZXcgUC5vUShtLG4pKSl9fSwKYWg6ZnVuY3Rpb24oKXt2YXIgdD11LnguYSh0aGlzLmMp
-CnRoaXMuYz1udWxsCnJldHVybiB0aGlzLk44KHQpfSwKTjg6ZnVuY3Rpb24oYSl7dmFyIHQscyxyCmZv
-cih0PWEscz1udWxsO3QhPW51bGw7cz10LHQ9cil7cj10LmEKdC5hPXN9cmV0dXJuIHN9LApISDpmdW5j
-dGlvbihhKXt2YXIgdCxzPXRoaXMscj1zLiR0aQpyLkMoIjEvIikuYShhKQppZihyLkMoImI4PDE+Iiku
-YihhKSlpZihyLmIoYSkpUC5BOShhLHMpCmVsc2UgUC5rMyhhLHMpCmVsc2V7dD1zLmFoKCkKcj1yLmMK
-YT1yLmEoci5hKGEpKQpzLmE9NApzLmM9YQpQLkhaKHMsdCl9fSwKWDI6ZnVuY3Rpb24oYSl7dmFyIHQs
-cz10aGlzCnMuJHRpLmMuYShhKQp0PXMuYWgoKQpzLmE9NApzLmM9YQpQLkhaKHMsdCl9LApaTDpmdW5j
-dGlvbihhLGIpe3ZhciB0LHMscj10aGlzCnUubC5hKGIpCnQ9ci5haCgpCnM9UC5UbChhLGIpCnIuYT04
-CnIuYz1zClAuSFoocix0KX0sClhmOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMscz10LiR0aQpzLkMoIjEv
-IikuYShhKQppZihzLkMoImI4PDE+IikuYihhKSl7dC5jVShhKQpyZXR1cm59dC5hPTEKUC5UayhudWxs
-LG51bGwsdC5iLHUuTS5hKG5ldyBQLnJIKHQsYSkpKX0sCmNVOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMs
-cz10LiR0aQpzLkMoImI4PDE+IikuYShhKQppZihzLmIoYSkpe2lmKGEuYT09PTgpe3QuYT0xClAuVGso
-bnVsbCxudWxsLHQuYix1Lk0uYShuZXcgUC5LRih0LGEpKSl9ZWxzZSBQLkE5KGEsdCkKcmV0dXJufVAu
-azMoYSx0KX0sCk5rOmZ1bmN0aW9uKGEsYil7dGhpcy5hPTEKUC5UayhudWxsLG51bGwsdGhpcy5iLHUu
-TS5hKG5ldyBQLlpMKHRoaXMsYSxiKSkpfSwKJGliODoxfQpQLmRhLnByb3RvdHlwZT17CiQwOmZ1bmN0
-aW9uKCl7UC5IWih0aGlzLmEsdGhpcy5iKX0sCiRTOjB9ClAub1EucHJvdG90eXBlPXsKJDA6ZnVuY3Rp
-b24oKXtQLkhaKHRoaXMuYix0aGlzLmEuYSl9LAokUzowfQpQLnBWLnByb3RvdHlwZT17CiQxOmZ1bmN0
-aW9uKGEpe3ZhciB0PXRoaXMuYQp0LmE9MAp0LkhIKGEpfSwKJFM6MTJ9ClAuVTcucHJvdG90eXBlPXsK
-JDI6ZnVuY3Rpb24oYSxiKXt1LmwuYShiKQp0aGlzLmEuWkwoYSxiKX0sCiRDOiIkMiIsCiRSOjIsCiRT
-OjM0fQpQLnZyLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7dGhpcy5hLlpMKHRoaXMuYix0aGlzLmMp
-fSwKJFM6MH0KUC5ySC5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3ZhciB0PXRoaXMuYQp0LlgyKHQu
-JHRpLmMuYSh0aGlzLmIpKX0sCiRTOjB9ClAuS0YucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXtQLkE5
-KHRoaXMuYix0aGlzLmEpfSwKJFM6MH0KUC5aTC5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3RoaXMu
-YS5aTCh0aGlzLmIsdGhpcy5jKX0sCiRTOjB9ClAuUlQucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt2
-YXIgdCxzLHIscSxwLG8sbj10aGlzLG09bnVsbAp0cnl7cj1uLmEuYQptPXIuYi5iLnp6KHUuZk8uYShy
-LmQpLHUueil9Y2F0Y2gocSl7dD1ILlJ1KHEpCnM9SC50cyhxKQppZihuLmMpe3I9dS5uLmEobi5iLmEu
-YykuYQpwPXQKcD1yPT1udWxsP3A9PW51bGw6cj09PXAKcj1wfWVsc2Ugcj0hMQpwPW4uYQppZihyKXAu
-Yz11Lm4uYShuLmIuYS5jKQplbHNlIHAuYz1QLlRsKHQscykKcC5iPSEwCnJldHVybn1pZih1LmMuYiht
-KSl7aWYobSBpbnN0YW5jZW9mIFAudnMmJm0uYT49NCl7aWYobS5hPT09OCl7cj1uLmEKci5jPXUubi5h
-KG0uYykKci5iPSEwfXJldHVybn1vPW4uYi5hCnI9bi5hCnIuYz1tLlc3KG5ldyBQLmpaKG8pLHUueikK
-ci5iPSExfX0sCiRTOjF9ClAualoucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMu
-YX0sCiRTOjM4fQpQLnJxLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscCxvLG4s
-bQp0cnl7cj10aGlzLmEKcT1yLmEKcD1xLiR0aQpvPXAuYwpuPW8uYSh0aGlzLmIpCnIuYz1xLmIuYi5i
-dihwLkMoIjIvKDEpIikuYShxLmQpLG4scC5DKCIyLyIpLG8pfWNhdGNoKG0pe3Q9SC5SdShtKQpzPUgu
-dHMobSkKcj10aGlzLmEKci5jPVAuVGwodCxzKQpyLmI9ITB9fSwKJFM6MX0KUC5SVy5wcm90b3R5cGU9
-ewokMDpmdW5jdGlvbigpe3ZhciB0LHMscixxLHAsbyxuLG0sbD10aGlzCnRyeXt0PXUubi5hKGwuYS5h
-LmMpCnE9bC5iCmlmKEgub1QocS5hLkhSKHQpKSYmcS5hLmUhPW51bGwpe3EuYz1xLmEuS3codCkKcS5i
-PSExfX1jYXRjaChwKXtzPUguUnUocCkKcj1ILnRzKHApCnE9dS5uLmEobC5hLmEuYykKbz1xLmEKbj1z
-Cm09bC5iCmlmKG89PW51bGw/bj09bnVsbDpvPT09biltLmM9cQplbHNlIG0uYz1QLlRsKHMscikKbS5i
-PSEwfX0sCiRTOjF9ClAuT00ucHJvdG90eXBlPXt9ClAucWgucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24o
-YSl7dmFyIHQscyxyPXRoaXMscT17fSxwPW5ldyBQLnZzKCQuWDMsdS5mSikKcS5hPTAKdD1ILkxoKHIp
-CnM9dC5DKCJ+KDEpIikuYShuZXcgUC5CNShxLHIpKQp1Lk0uYShuZXcgUC51TyhxLHApKQpXLkpFKHIu
-YSxyLmIscywhMSx0LmMpCnJldHVybiBwfX0KUC5CNS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtI
-LkxoKHRoaXMuYikuYy5hKGEpOysrdGhpcy5hLmF9LAokUzpmdW5jdGlvbigpe3JldHVybiBILkxoKHRo
-aXMuYikuQygiYzgoMSkiKX19ClAudU8ucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt0aGlzLmIuSEgo
-dGhpcy5hLmEpfSwKJFM6MH0KUC5NTy5wcm90b3R5cGU9e30KUC5rVC5wcm90b3R5cGU9e30KUC54SS5w
-cm90b3R5cGU9e30KUC5PSC5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3JldHVybiBILmQodGhpcy5h
-KX0sCiRpWFM6MSwKZ0lJOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYn19ClAubTAucHJvdG90eXBlPXsk
-aUpCOjF9ClAucEsucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt2YXIgdD1ILmIodGhpcy5hKQp0LnN0
-YWNrPUouQWModGhpcy5iKQp0aHJvdyB0fSwKJFM6MH0KUC5KaS5wcm90b3R5cGU9ewpiSDpmdW5jdGlv
-bihhKXt2YXIgdCxzLHIscT1udWxsCnUuTS5hKGEpCnRyeXtpZihDLk5VPT09JC5YMyl7YS4kMCgpCnJl
-dHVybn1QLlQ4KHEscSx0aGlzLGEsdS5IKX1jYXRjaChyKXt0PUguUnUocikKcz1ILnRzKHIpClAuTDIo
-cSxxLHRoaXMsdCx1LmwuYShzKSl9fSwKRGw6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxPW51bGwK
-Yy5DKCJ+KDApIikuYShhKQpjLmEoYikKdHJ5e2lmKEMuTlU9PT0kLlgzKXthLiQxKGIpCnJldHVybn1Q
-Lnl2KHEscSx0aGlzLGEsYix1LkgsYyl9Y2F0Y2gocil7dD1ILlJ1KHIpCnM9SC50cyhyKQpQLkwyKHEs
-cSx0aGlzLHQsdS5sLmEocykpfX0sClJUOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBQLmhqKHRoaXMs
-Yi5DKCIwKCkiKS5hKGEpLGIpfSwKR1k6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLlZwKHRoaXMsdS5N
-LmEoYSkpfSwKUHk6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IFAuT1IodGhpcyxiLkMoIn4oMCkiKS5h
-KGEpLGIpfSwKcTpmdW5jdGlvbihhLGIpe3JldHVybiBudWxsfSwKeno6ZnVuY3Rpb24oYSxiKXtiLkMo
-IjAoKSIpLmEoYSkKaWYoJC5YMz09PUMuTlUpcmV0dXJuIGEuJDAoKQpyZXR1cm4gUC5UOChudWxsLG51
-bGwsdGhpcyxhLGIpfSwKYnY6ZnVuY3Rpb24oYSxiLGMsZCl7Yy5DKCJAPDA+IikuS3EoZCkuQygiMSgy
-KSIpLmEoYSkKZC5hKGIpCmlmKCQuWDM9PT1DLk5VKXJldHVybiBhLiQxKGIpCnJldHVybiBQLnl2KG51
-bGwsbnVsbCx0aGlzLGEsYixjLGQpfSwKcnA6ZnVuY3Rpb24oYSxiLGMsZCxlLGYpe2QuQygiQDwwPiIp
-LktxKGUpLktxKGYpLkMoIjEoMiwzKSIpLmEoYSkKZS5hKGIpCmYuYShjKQppZigkLlgzPT09Qy5OVSly
-ZXR1cm4gYS4kMihiLGMpCnJldHVybiBQLlF4KG51bGwsbnVsbCx0aGlzLGEsYixjLGQsZSxmKX0sCkxq
-OmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybiBiLkMoIkA8MD4iKS5LcShjKS5LcShkKS5DKCIxKDIsMyki
-KS5hKGEpfX0KUC5oai5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmEuenoodGhp
-cy5iLHRoaXMuYyl9LAokUzpmdW5jdGlvbigpe3JldHVybiB0aGlzLmMuQygiMCgpIil9fQpQLlZwLnBy
-b3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYS5iSCh0aGlzLmIpfSwKJFM6MX0KUC5P
-Ui5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmMKcmV0dXJuIHRoaXMuYS5EbCh0
-aGlzLmIsdC5hKGEpLHQpfSwKJFM6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5jLkMoIn4oMCkiKX19ClAu
-YjYucHJvdG90eXBlPXsKZ2t6OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMscz1uZXcgUC5sbSh0LHQucixI
-LkxoKHQpLkMoImxtPDE+IikpCnMuYz10LmUKcmV0dXJuIHN9LApnQTpmdW5jdGlvbihhKXtyZXR1cm4g
-dGhpcy5hfSwKdGc6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzCmlmKHR5cGVvZiBiPT0ic3RyaW5nIiYmYiE9
-PSJfX3Byb3RvX18iKXt0PXRoaXMuYgppZih0PT1udWxsKXJldHVybiExCnJldHVybiB1LkouYSh0W2Jd
-KSE9bnVsbH1lbHNle3M9dGhpcy5QUihiKQpyZXR1cm4gc319LApQUjpmdW5jdGlvbihhKXt2YXIgdD10
-aGlzLmQKaWYodD09bnVsbClyZXR1cm4hMQpyZXR1cm4gdGhpcy5ERih0W3RoaXMuTihhKV0sYSk+PTB9
-LAppOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyPXRoaXMKSC5MaChyKS5jLmEoYikKaWYodHlwZW9mIGI9
-PSJzdHJpbmciJiZiIT09Il9fcHJvdG9fXyIpe3Q9ci5iCnJldHVybiByLlModD09bnVsbD9yLmI9UC5U
-MigpOnQsYil9ZWxzZSBpZih0eXBlb2YgYj09Im51bWJlciImJihiJjEwNzM3NDE4MjMpPT09Yil7cz1y
-LmMKcmV0dXJuIHIuUyhzPT1udWxsP3IuYz1QLlQyKCk6cyxiKX1lbHNlIHJldHVybiByLkI3KGIpfSwK
-Qjc6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHE9dGhpcwpILkxoKHEpLmMuYShhKQp0PXEuZAppZih0PT1u
-dWxsKXQ9cS5kPVAuVDIoKQpzPXEuTihhKQpyPXRbc10KaWYocj09bnVsbCl0W3NdPVtxLnlvKGEpXQpl
-bHNle2lmKHEuREYocixhKT49MClyZXR1cm4hMQpyLnB1c2gocS55byhhKSl9cmV0dXJuITB9LApSOmZ1
-bmN0aW9uKGEsYil7dmFyIHQ9dGhpcwppZih0eXBlb2YgYj09InN0cmluZyImJmIhPT0iX19wcm90b19f
-IilyZXR1cm4gdC5INCh0LmIsYikKZWxzZSBpZih0eXBlb2YgYj09Im51bWJlciImJihiJjEwNzM3NDE4
-MjMpPT09YilyZXR1cm4gdC5INCh0LmMsYikKZWxzZSByZXR1cm4gdC5xZyhiKX0sCnFnOmZ1bmN0aW9u
-KGEpe3ZhciB0LHMscixxLHA9dGhpcyxvPXAuZAppZihvPT1udWxsKXJldHVybiExCnQ9cC5OKGEpCnM9
-b1t0XQpyPXAuREYocyxhKQppZihyPDApcmV0dXJuITEKcT1zLnNwbGljZShyLDEpWzBdCmlmKDA9PT1z
-Lmxlbmd0aClkZWxldGUgb1t0XQpwLkdTKHEpCnJldHVybiEwfSwKUzpmdW5jdGlvbihhLGIpe0guTGgo
-dGhpcykuYy5hKGIpCmlmKHUuSi5hKGFbYl0pIT1udWxsKXJldHVybiExCmFbYl09dGhpcy55byhiKQpy
-ZXR1cm4hMH0sCkg0OmZ1bmN0aW9uKGEsYil7dmFyIHQKaWYoYT09bnVsbClyZXR1cm4hMQp0PXUuSi5h
-KGFbYl0pCmlmKHQ9PW51bGwpcmV0dXJuITEKdGhpcy5HUyh0KQpkZWxldGUgYVtiXQpyZXR1cm4hMH0s
-Clg6ZnVuY3Rpb24oKXt0aGlzLnI9MTA3Mzc0MTgyMyZ0aGlzLnIrMX0sCnlvOmZ1bmN0aW9uKGEpe3Zh
-ciB0LHM9dGhpcyxyPW5ldyBQLmJuKEguTGgocykuYy5hKGEpKQppZihzLmU9PW51bGwpcy5lPXMuZj1y
-CmVsc2V7dD1zLmYKdC50b1N0cmluZwpyLmM9dApzLmY9dC5iPXJ9KytzLmEKcy5YKCkKcmV0dXJuIHJ9
-LApHUzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLHM9YS5jLHI9YS5iCmlmKHM9PW51bGwpdC5lPXIKZWxz
-ZSBzLmI9cgppZihyPT1udWxsKXQuZj1zCmVsc2Ugci5jPXM7LS10LmEKdC5YKCl9LApOOmZ1bmN0aW9u
-KGEpe3JldHVybiBKLmhmKGEpJjEwNzM3NDE4MjN9LApERjpmdW5jdGlvbihhLGIpe3ZhciB0LHMKaWYo
-YT09bnVsbClyZXR1cm4tMQp0PWEubGVuZ3RoCmZvcihzPTA7czx0OysrcylpZihKLlJNKGFbc10uYSxi
-KSlyZXR1cm4gcwpyZXR1cm4tMX19ClAuYm4ucHJvdG90eXBlPXt9ClAubG0ucHJvdG90eXBlPXsKZ2w6
-ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwKRjpmdW5jdGlvbigpe3ZhciB0PXRoaXMscz10LmMscj10
-LmEKaWYodC5iIT09ci5yKXRocm93IEguYihQLmE0KHIpKQplbHNlIGlmKHM9PW51bGwpe3Quc2oobnVs
-bCkKcmV0dXJuITF9ZWxzZXt0LnNqKHQuJHRpLmMuYShzLmEpKQp0LmM9cy5iCnJldHVybiEwfX0sCnNq
-OmZ1bmN0aW9uKGEpe3RoaXMuZD10aGlzLiR0aS5jLmEoYSl9LAokaUFuOjF9ClAubVcucHJvdG90eXBl
-PXt9ClAuTFUucHJvdG90eXBlPXskaWJROjEsJGljWDoxLCRpek06MX0KUC5sRC5wcm90b3R5cGU9ewpn
-a3o6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBILmE3KGEsdGhpcy5nQShhKSxILnEoYSkuQygiYTc8bEQu
-RT4iKSl9LApFOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMucShhLGIpfSwKSzpmdW5jdGlvbihhLGIp
-e3ZhciB0LHMKSC5xKGEpLkMoIn4obEQuRSkiKS5hKGIpCnQ9dGhpcy5nQShhKQpmb3Iocz0wO3M8dDsr
-K3Mpe2IuJDEodGhpcy5xKGEscykpCmlmKHQhPT10aGlzLmdBKGEpKXRocm93IEguYihQLmE0KGEpKX19
-LApFMjpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9SC5xKGEpCnJldHVybiBuZXcgSC5sSihhLHQuS3EoYyku
-QygiMShsRC5FKSIpLmEoYiksdC5DKCJAPGxELkU+IikuS3EoYykuQygibEo8MSwyPiIpKX0sCmR1OmZ1
-bmN0aW9uKGEsYixjLGQpe3ZhciB0CkgucShhKS5DKCJsRC5FIikuYShkKQpQLmpCKGIsYyx0aGlzLmdB
-KGEpKQpmb3IodD1iO3Q8YzsrK3QpdGhpcy5ZKGEsdCxkKX0sClo6ZnVuY3Rpb24oYSl7cmV0dXJuIFAu
-V0UoYSwiWyIsIl0iKX19ClAuaWwucHJvdG90eXBlPXt9ClAucmEucHJvdG90eXBlPXsKJDI6ZnVuY3Rp
-b24oYSxiKXt2YXIgdCxzPXRoaXMuYQppZighcy5hKXRoaXMuYi5hKz0iLCAiCnMuYT0hMQpzPXRoaXMu
-Ygp0PXMuYSs9SC5kKGEpCnMuYT10KyI6ICIKcy5hKz1ILmQoYil9LAokUzozOX0KUC5Zay5wcm90b3R5
-cGU9ewpLOmZ1bmN0aW9uKGEsYil7dmFyIHQscwpILkxoKHRoaXMpLkMoIn4oWWsuSyxZay5WKSIpLmEo
-YikKZm9yKHQ9Si5JVCh0aGlzLmdWKCkpO3QuRigpOyl7cz10LmdsKCkKYi4kMihzLHRoaXMucSgwLHMp
-KX19LApnUHU6ZnVuY3Rpb24oYSl7cmV0dXJuIEouTTEodGhpcy5nVigpLG5ldyBQLnlRKHRoaXMpLEgu
-TGgodGhpcykuQygiTjM8WWsuSyxZay5WPiIpKX0sCng0OmZ1bmN0aW9uKGEpe3JldHVybiBKLnpsKHRo
-aXMuZ1YoKSxhKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiBKLkgodGhpcy5nVigpKX0sClo6ZnVuY3Rp
-b24oYSl7cmV0dXJuIFAubk8odGhpcyl9LAokaVowOjF9ClAueVEucHJvdG90eXBlPXsKJDE6ZnVuY3Rp
-b24oYSl7dmFyIHQ9dGhpcy5hLHM9SC5MaCh0KQpzLkMoIllrLksiKS5hKGEpCnJldHVybiBuZXcgUC5O
-MyhhLHQucSgwLGEpLHMuQygiQDxZay5LPiIpLktxKHMuQygiWWsuViIpKS5DKCJOMzwxLDI+IikpfSwK
-JFM6ZnVuY3Rpb24oKXtyZXR1cm4gSC5MaCh0aGlzLmEpLkMoIk4zPFlrLkssWWsuVj4oWWsuSykiKX19
-ClAuS1AucHJvdG90eXBlPXsKWTpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9SC5MaCh0aGlzKQp0LmMuYShi
-KQp0LlFbMV0uYShjKQp0aHJvdyBILmIoUC5MNCgiQ2Fubm90IG1vZGlmeSB1bm1vZGlmaWFibGUgbWFw
-IikpfX0KUC5Qbi5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuYS5xKDAsYil9
-LApZOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1ILkxoKHRoaXMpCnRoaXMuYS5ZKDAsdC5jLmEoYiksdC5R
-WzFdLmEoYykpfSwKeDQ6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS54NChhKX0sCks6ZnVuY3Rpb24o
-YSxiKXt0aGlzLmEuSygwLEguTGgodGhpcykuQygifigxLDIpIikuYShiKSl9LApnQTpmdW5jdGlvbihh
-KXt2YXIgdD10aGlzLmEKcmV0dXJuIHQuZ0EodCl9LApaOmZ1bmN0aW9uKGEpe3JldHVybiBKLkFjKHRo
-aXMuYSl9LApnUHU6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCnJldHVybiB0LmdQdSh0KX0sCiRpWjA6
-MX0KUC5Hai5wcm90b3R5cGU9e30KUC5NYS5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3JldHVybiBQ
-LldFKHRoaXMsInsiLCJ9Iil9fQpQLlZqLnByb3RvdHlwZT17JGliUToxLCRpY1g6MSwkaXh1OjF9ClAu
-WHYucHJvdG90eXBlPXsKRlY6ZnVuY3Rpb24oYSxiKXt2YXIgdApmb3IodD1KLklUKEguTGgodGhpcyku
-QygiY1g8MT4iKS5hKGIpKTt0LkYoKTspdGhpcy5pKDAsdC5nbCgpKX0sClo6ZnVuY3Rpb24oYSl7cmV0
-dXJuIFAuV0UodGhpcywieyIsIn0iKX0sCnpWOmZ1bmN0aW9uKGEsYil7dmFyIHQscz1QLnJqKHRoaXMs
-dGhpcy5yLEguTGgodGhpcykuYykKaWYoIXMuRigpKXJldHVybiIiCmlmKGI9PT0iIil7dD0iIgpkbyB0
-Kz1ILmQocy5kKQp3aGlsZShzLkYoKSl9ZWxzZXt0PUguZChzLmQpCmZvcig7cy5GKCk7KXQ9dCtiK0gu
-ZChzLmQpfXJldHVybiB0LmNoYXJDb2RlQXQoMCk9PTA/dDp0fSwKJGliUToxLAokaWNYOjEsCiRpeHU6
-MX0KUC5uWS5wcm90b3R5cGU9e30KUC5UQy5wcm90b3R5cGU9e30KUC5SVS5wcm90b3R5cGU9e30KUC51
-dy5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7dmFyIHQscz10aGlzLmIKaWYocz09bnVsbClyZXR1
-cm4gdGhpcy5jLnEoMCxiKQplbHNlIGlmKHR5cGVvZiBiIT0ic3RyaW5nIilyZXR1cm4gbnVsbAplbHNl
-e3Q9c1tiXQpyZXR1cm4gdHlwZW9mIHQ9PSJ1bmRlZmluZWQiP3RoaXMuZmIoYik6dH19LApnQTpmdW5j
-dGlvbihhKXtyZXR1cm4gdGhpcy5iPT1udWxsP3RoaXMuYy5hOnRoaXMuQ2YoKS5sZW5ndGh9LApnVjpm
-dW5jdGlvbigpe2lmKHRoaXMuYj09bnVsbCl7dmFyIHQ9dGhpcy5jCnJldHVybiBuZXcgSC5pNSh0LEgu
-TGgodCkuQygiaTU8MT4iKSl9cmV0dXJuIG5ldyBQLmk4KHRoaXMpfSwKWTpmdW5jdGlvbihhLGIsYyl7
-dmFyIHQscyxyPXRoaXMKaWYoci5iPT1udWxsKXIuYy5ZKDAsYixjKQplbHNlIGlmKHIueDQoYikpe3Q9
-ci5iCnRbYl09YwpzPXIuYQppZihzPT1udWxsP3QhPW51bGw6cyE9PXQpc1tiXT1udWxsfWVsc2Ugci5Y
-SygpLlkoMCxiLGMpfSwKeDQ6ZnVuY3Rpb24oYSl7aWYodGhpcy5iPT1udWxsKXJldHVybiB0aGlzLmMu
-eDQoYSkKcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh0aGlzLmEsYSl9
-LApLOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscD10aGlzCnUuY0EuYShiKQppZihwLmI9PW51bGwp
-cmV0dXJuIHAuYy5LKDAsYikKdD1wLkNmKCkKZm9yKHM9MDtzPHQubGVuZ3RoOysrcyl7cj10W3NdCnE9
-cC5iW3JdCmlmKHR5cGVvZiBxPT0idW5kZWZpbmVkIil7cT1QLlFlKHAuYVtyXSkKcC5iW3JdPXF9Yi4k
-MihyLHEpCmlmKHQhPT1wLmMpdGhyb3cgSC5iKFAuYTQocCkpfX0sCkNmOmZ1bmN0aW9uKCl7dmFyIHQ9
-dS5qLmEodGhpcy5jKQppZih0PT1udWxsKXQ9dGhpcy5jPUguVk0oT2JqZWN0LmtleXModGhpcy5hKSx1
-LnMpCnJldHVybiB0fSwKWEs6ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwLG89dGhpcwppZihvLmI9PW51
-bGwpcmV0dXJuIG8uYwp0PVAuRmwodS5OLHUueikKcz1vLkNmKCkKZm9yKHI9MDtxPXMubGVuZ3RoLHI8
-cTsrK3Ipe3A9c1tyXQp0LlkoMCxwLG8ucSgwLHApKX1pZihxPT09MClDLk5tLmkocywiIikKZWxzZSBD
-Lk5tLnNBKHMsMCkKby5hPW8uYj1udWxsCnJldHVybiBvLmM9dH0sCmZiOmZ1bmN0aW9uKGEpe3ZhciB0
-CmlmKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodGhpcy5hLGEpKXJldHVybiBu
-dWxsCnQ9UC5RZSh0aGlzLmFbYV0pCnJldHVybiB0aGlzLmJbYV09dH19ClAuaTgucHJvdG90eXBlPXsK
-Z0E6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCnJldHVybiB0LmdBKHQpfSwKRTpmdW5jdGlvbihhLGIp
-e3ZhciB0PXRoaXMuYQppZih0LmI9PW51bGwpdD10LmdWKCkuRSgwLGIpCmVsc2V7dD10LkNmKCkKaWYo
-YjwwfHxiPj10Lmxlbmd0aClyZXR1cm4gSC5rKHQsYikKdD10W2JdfXJldHVybiB0fSwKZ2t6OmZ1bmN0
-aW9uKGEpe3ZhciB0PXRoaXMuYQppZih0LmI9PW51bGwpe3Q9dC5nVigpCnQ9dC5na3oodCl9ZWxzZXt0
-PXQuQ2YoKQp0PW5ldyBKLm0xKHQsdC5sZW5ndGgsSC50Nih0KS5DKCJtMTwxPiIpKX1yZXR1cm4gdH0s
-CnRnOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuYS54NChiKX19ClAucGcucHJvdG90eXBlPXsKJDA6
-ZnVuY3Rpb24oKXt2YXIgdCxzCnRyeXt0PW5ldyBUZXh0RGVjb2RlcigidXRmLTgiLHtmYXRhbDp0cnVl
-fSkKcmV0dXJuIHR9Y2F0Y2gocyl7SC5SdShzKX1yZXR1cm4gbnVsbH0sCiRTOjQzfQpQLkNWLnByb3Rv
-dHlwZT17CnlyOmZ1bmN0aW9uKGEsYTAsYTEpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcs
-ZixlLGQsYyxiPSJJbnZhbGlkIGJhc2U2NCBlbmNvZGluZyBsZW5ndGggIgphMT1QLmpCKGEwLGExLGEu
-bGVuZ3RoKQp0PSQuVjcoKQpmb3Iocz1hMCxyPXMscT1udWxsLHA9LTEsbz0tMSxuPTA7czxhMTtzPW0p
-e209cysxCmw9Qy54Qi5XKGEscykKaWYobD09PTM3KXtrPW0rMgppZihrPD1hMSl7aj1ILm9vKEMueEIu
-VyhhLG0pKQppPUgub28oQy54Qi5XKGEsbSsxKSkKaD1qKjE2K2ktKGkmMjU2KQppZihoPT09MzcpaD0t
-MQptPWt9ZWxzZSBoPS0xfWVsc2UgaD1sCmlmKDA8PWgmJmg8PTEyNyl7aWYoaDwwfHxoPj10Lmxlbmd0
-aClyZXR1cm4gSC5rKHQsaCkKZz10W2hdCmlmKGc+PTApe2g9Qy54Qi5tKCJBQkNERUZHSElKS0xNTk9Q
-UVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvIixnKQppZihoPT09
-bCljb250aW51ZQpsPWh9ZWxzZXtpZihnPT09LTEpe2lmKHA8MCl7Zj1xPT1udWxsP251bGw6cS5hLmxl
-bmd0aAppZihmPT1udWxsKWY9MApwPWYrKHMtcikKbz1zfSsrbgppZihsPT09NjEpY29udGludWV9bD1o
-fWlmKGchPT0tMil7aWYocT09bnVsbCl7cT1uZXcgUC5SbigiIikKZj1xfWVsc2UgZj1xCmYuYSs9Qy54
-Qi5OaihhLHIscykKZi5hKz1ILkx3KGwpCnI9bQpjb250aW51ZX19dGhyb3cgSC5iKFAucnIoIkludmFs
-aWQgYmFzZTY0IGRhdGEiLGEscykpfWlmKHEhPW51bGwpe2Y9cS5hKz1DLnhCLk5qKGEscixhMSkKZT1m
-Lmxlbmd0aAppZihwPj0wKVAueE0oYSxvLGExLHAsbixlKQplbHNle2Q9Qy5qbi56WShlLTEsNCkrMQpp
-ZihkPT09MSl0aHJvdyBILmIoUC5ycihiLGEsYTEpKQpmb3IoO2Q8NDspe2YrPSI9IgpxLmE9ZjsrK2R9
-fWY9cS5hCnJldHVybiBDLnhCLmk3KGEsYTAsYTEsZi5jaGFyQ29kZUF0KDApPT0wP2Y6Zil9Yz1hMS1h
-MAppZihwPj0wKVAueE0oYSxvLGExLHAsbixjKQplbHNle2Q9Qy5qbi56WShjLDQpCmlmKGQ9PT0xKXRo
-cm93IEguYihQLnJyKGIsYSxhMSkpCmlmKGQ+MSlhPUMueEIuaTcoYSxhMSxhMSxkPT09Mj8iPT0iOiI9
-Iil9cmV0dXJuIGF9fQpQLlU4LnByb3RvdHlwZT17fQpQLlVrLnByb3RvdHlwZT17fQpQLndJLnByb3Rv
-dHlwZT17fQpQLlppLnByb3RvdHlwZT17fQpQLmJ5LnByb3RvdHlwZT17CnBXOmZ1bmN0aW9uKGEsYixj
-KXt2YXIgdAp1LmNhLmEoYykKdD1QLkJTKGIsdGhpcy5nSGUoKS5hKQpyZXR1cm4gdH0sCmdIZTpmdW5j
-dGlvbigpe3JldHVybiBDLkEzfX0KUC5NeC5wcm90b3R5cGU9e30KUC51NS5wcm90b3R5cGU9ewpnWkU6
-ZnVuY3Rpb24oKXtyZXR1cm4gQy5Ra319ClAuRTMucHJvdG90eXBlPXsKV0o6ZnVuY3Rpb24oYSl7dmFy
-IHQscyxyPVAuakIoMCxudWxsLGEubGVuZ3RoKSxxPXItMAppZihxPT09MClyZXR1cm4gbmV3IFVpbnQ4
-QXJyYXkoMCkKdD1uZXcgVWludDhBcnJheShxKjMpCnM9bmV3IFAuUncodCkKaWYocy5HeChhLDAscikh
-PT1yKXMuTzYoSi5hNihhLHItMSksMCkKcmV0dXJuIG5ldyBVaW50OEFycmF5KHQuc3ViYXJyYXkoMCxI
-LnJNKDAscy5iLHQubGVuZ3RoKSkpfX0KUC5Sdy5wcm90b3R5cGU9ewpPNjpmdW5jdGlvbihhLGIpe3Zh
-ciB0LHM9dGhpcyxyPXMuYyxxPXMuYixwPXErMSxvPXIubGVuZ3RoCmlmKChiJjY0NTEyKT09PTU2MzIw
-KXt0PTY1NTM2KygoYSYxMDIzKTw8MTApfGImMTAyMwpzLmI9cAppZihxPj1vKXJldHVybiBILmsocixx
-KQpyW3FdPTI0MHx0Pj4+MTgKcT1zLmI9cCsxCmlmKHA+PW8pcmV0dXJuIEguayhyLHApCnJbcF09MTI4
-fHQ+Pj4xMiY2MwpwPXMuYj1xKzEKaWYocT49bylyZXR1cm4gSC5rKHIscSkKcltxXT0xMjh8dD4+PjYm
-NjMKcy5iPXArMQppZihwPj1vKXJldHVybiBILmsocixwKQpyW3BdPTEyOHx0JjYzCnJldHVybiEwfWVs
-c2V7cy5iPXAKaWYocT49bylyZXR1cm4gSC5rKHIscSkKcltxXT0yMjR8YT4+PjEyCnE9cy5iPXArMQpp
-ZihwPj1vKXJldHVybiBILmsocixwKQpyW3BdPTEyOHxhPj4+NiY2MwpzLmI9cSsxCmlmKHE+PW8pcmV0
-dXJuIEguayhyLHEpCnJbcV09MTI4fGEmNjMKcmV0dXJuITF9fSwKR3g6ZnVuY3Rpb24oYSxiLGMpe3Zh
-ciB0LHMscixxLHAsbyxuLG09dGhpcwppZihiIT09YyYmKEMueEIubShhLGMtMSkmNjQ1MTIpPT09NTUy
-OTYpLS1jCmZvcih0PW0uYyxzPXQubGVuZ3RoLHI9YjtyPGM7KytyKXtxPUMueEIuVyhhLHIpCmlmKHE8
-PTEyNyl7cD1tLmIKaWYocD49cylicmVhawptLmI9cCsxCnRbcF09cX1lbHNlIGlmKChxJjY0NTEyKT09
-PTU1Mjk2KXtpZihtLmIrMz49cylicmVhawpvPXIrMQppZihtLk82KHEsQy54Qi5XKGEsbykpKXI9b31l
-bHNlIGlmKHE8PTIwNDcpe3A9bS5iCm49cCsxCmlmKG4+PXMpYnJlYWsKbS5iPW4KaWYocD49cylyZXR1
-cm4gSC5rKHQscCkKdFtwXT0xOTJ8cT4+PjYKbS5iPW4rMQp0W25dPTEyOHxxJjYzfWVsc2V7cD1tLmIK
-aWYocCsyPj1zKWJyZWFrCm49bS5iPXArMQppZihwPj1zKXJldHVybiBILmsodCxwKQp0W3BdPTIyNHxx
-Pj4+MTIKcD1tLmI9bisxCmlmKG4+PXMpcmV0dXJuIEguayh0LG4pCnRbbl09MTI4fHE+Pj42JjYzCm0u
-Yj1wKzEKaWYocD49cylyZXR1cm4gSC5rKHQscCkKdFtwXT0xMjh8cSY2M319cmV0dXJuIHJ9fQpQLkdZ
-LnByb3RvdHlwZT17CldKOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAsbyxuLG0sbAp1LkwuYShhKQp0
-PVAua3koITEsYSwwLG51bGwpCmlmKHQhPW51bGwpcmV0dXJuIHQKcz1QLmpCKDAsbnVsbCxKLkgoYSkp
-CnI9UC5jUChhLDAscykKaWYocj4wKXtxPVAuSE0oYSwwLHIpCmlmKHI9PT1zKXJldHVybiBxCnA9bmV3
-IFAuUm4ocSkKbz1yCm49ITF9ZWxzZXtwPW5ldyBQLlJuKCIiKQpvPTAKbj0hMH1tPW5ldyBQLmJ6KCEx
-LHApCm0uYz1uCm0uTUUoYSxvLHMpCmlmKG0uZT4wKXtILnZoKFAucnIoIlVuZmluaXNoZWQgVVRGLTgg
-b2N0ZXQgc2VxdWVuY2UiLGEscykpCnAuYSs9SC5Mdyg2NTUzMykKbS5mPW0uZT1tLmQ9MH1sPXAuYQpy
-ZXR1cm4gbC5jaGFyQ29kZUF0KDApPT0wP2w6bH19ClAuYnoucHJvdG90eXBlPXsKTUU6ZnVuY3Rpb24o
-YSxiLGMpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGosaSxoPXRoaXMsZz0iQmFkIFVURi04IGVuY29k
-aW5nIDB4Igp1LkwuYShhKQp0PWguZApzPWguZQpyPWguZgpoLmY9aC5lPWguZD0wCiRsYWJlbDAkMDpm
-b3IocT1KLlU2KGEpLHA9aC5iLG89YjshMDtvPWopeyRsYWJlbDEkMTppZihzPjApe2Rve2lmKG89PT1j
-KWJyZWFrICRsYWJlbDAkMApuPXEucShhLG8pCmlmKHR5cGVvZiBuIT09Im51bWJlciIpcmV0dXJuIG4u
-ek0oKQppZigobiYxOTIpIT09MTI4KXttPVAucnIoZytDLmpuLldaKG4sMTYpLGEsbykKdGhyb3cgSC5i
-KG0pfWVsc2V7dD0odDw8NnxuJjYzKT4+PjA7LS1zOysrb319d2hpbGUocz4wKQptPXItMQppZihtPDB8
-fG0+PTQpcmV0dXJuIEguayhDLkdiLG0pCmlmKHQ8PUMuR2JbbV0pe209UC5ycigiT3ZlcmxvbmcgZW5j
-b2Rpbmcgb2YgMHgiK0Muam4uV1oodCwxNiksYSxvLXItMSkKdGhyb3cgSC5iKG0pfWlmKHQ+MTExNDEx
-MSl7bT1QLnJyKCJDaGFyYWN0ZXIgb3V0c2lkZSB2YWxpZCBVbmljb2RlIHJhbmdlOiAweCIrQy5qbi5X
-Wih0LDE2KSxhLG8tci0xKQp0aHJvdyBILmIobSl9aWYoIWguY3x8dCE9PTY1Mjc5KXAuYSs9SC5Mdyh0
-KQpoLmM9ITF9Zm9yKG09bzxjO207KXtsPVAuY1AoYSxvLGMpCmlmKGw+MCl7aC5jPSExCms9bytsCnAu
-YSs9UC5ITShhLG8saykKaWYoaz09PWMpYnJlYWt9ZWxzZSBrPW8Kaj1rKzEKbj1xLnEoYSxrKQppZih0
-eXBlb2YgbiE9PSJudW1iZXIiKXJldHVybiBuLkooKQppZihuPDApe2k9UC5ycigiTmVnYXRpdmUgVVRG
-LTggY29kZSB1bml0OiAtMHgiK0Muam4uV1ooLW4sMTYpLGEsai0xKQp0aHJvdyBILmIoaSl9ZWxzZXtp
-ZigobiYyMjQpPT09MTkyKXt0PW4mMzEKcz0xCnI9MQpjb250aW51ZSAkbGFiZWwwJDB9aWYoKG4mMjQw
-KT09PTIyNCl7dD1uJjE1CnM9MgpyPTIKY29udGludWUgJGxhYmVsMCQwfWlmKChuJjI0OCk9PT0yNDAm
-Jm48MjQ1KXt0PW4mNwpzPTMKcj0zCmNvbnRpbnVlICRsYWJlbDAkMH1pPVAucnIoZytDLmpuLldaKG4s
-MTYpLGEsai0xKQp0aHJvdyBILmIoaSl9fWJyZWFrICRsYWJlbDAkMH1pZihzPjApe2guZD10CmguZT1z
-CmguZj1yfX19ClAuV0YucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIKdS5mby5h
-KGEpCnQ9dGhpcy5iCnM9dGhpcy5hCnQuYSs9cy5hCnI9dC5hKz1ILmQoYS5hKQp0LmE9cisiOiAiCnQu
-YSs9UC5oKGIpCnMuYT0iLCAifSwKJFM6NDR9ClAuYTIucHJvdG90eXBlPXt9ClAuaVAucHJvdG90eXBl
-PXsKRE46ZnVuY3Rpb24oYSxiKXtpZihiPT1udWxsKXJldHVybiExCnJldHVybiBiIGluc3RhbmNlb2Yg
-UC5pUCYmdGhpcy5hPT09Yi5hJiYhMH0sCmdpTzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEKcmV0dXJu
-KHReQy5qbi53Ryh0LDMwKSkmMTA3Mzc0MTgyM30sClo6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcyxzPVAu
-R3EoSC50Sih0KSkscj1QLmgwKEguTlModCkpLHE9UC5oMChILmpBKHQpKSxwPVAuaDAoSC5JWCh0KSks
-bz1QLmgwKEguY2godCkpLG49UC5oMChILkpkKHQpKSxtPVAuVngoSC5WYSh0KSksbD1zKyItIityKyIt
-IitxKyIgIitwKyI6IitvKyI6IituKyIuIittCnJldHVybiBsfX0KUC5DUC5wcm90b3R5cGU9e30KUC5Y
-Uy5wcm90b3R5cGU9ewpnSUk6ZnVuY3Rpb24oKXtyZXR1cm4gSC50cyh0aGlzLiR0aHJvd25Kc0Vycm9y
-KX19ClAuQzYucHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEKaWYodCE9bnVsbCly
-ZXR1cm4iQXNzZXJ0aW9uIGZhaWxlZDogIitQLmgodCkKcmV0dXJuIkFzc2VydGlvbiBmYWlsZWQifX0K
-UC5MSy5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3JldHVybiJUaHJvdyBvZiBudWxsLiJ9fQpQLkFU
-LnByb3RvdHlwZT17CmdMOmZ1bmN0aW9uKCl7cmV0dXJuIkludmFsaWQgYXJndW1lbnQiKyghdGhpcy5h
-PyIocykiOiIiKX0sCmd1OmZ1bmN0aW9uKCl7cmV0dXJuIiJ9LApaOmZ1bmN0aW9uKGEpe3ZhciB0LHMs
-cj10aGlzLHE9ci5jLHA9cT09bnVsbD8iIjoiICgiK3ErIikiLG89ci5kLG49bz09bnVsbD8iIjoiOiAi
-K0guZChvKSxtPXIuZ0woKStwK24KaWYoIXIuYSlyZXR1cm4gbQp0PXIuZ3UoKQpzPVAuaChyLmIpCnJl
-dHVybiBtK3QrIjogIitzfX0KUC5iSi5wcm90b3R5cGU9ewpnTDpmdW5jdGlvbigpe3JldHVybiJSYW5n
-ZUVycm9yIn0sCmd1OmZ1bmN0aW9uKCl7dmFyIHQscz10aGlzLmUscj10aGlzLmYKaWYocz09bnVsbCl0
-PXIhPW51bGw/IjogTm90IGxlc3MgdGhhbiBvciBlcXVhbCB0byAiK0guZChyKToiIgplbHNlIGlmKHI9
-PW51bGwpdD0iOiBOb3QgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICIrSC5kKHMpCmVsc2UgaWYocj5z
-KXQ9IjogTm90IGluIHJhbmdlICIrSC5kKHMpKyIuLiIrSC5kKHIpKyIsIGluY2x1c2l2ZSIKZWxzZSB0
-PXI8cz8iOiBWYWxpZCB2YWx1ZSByYW5nZSBpcyBlbXB0eSI6IjogT25seSB2YWxpZCB2YWx1ZSBpcyAi
-K0guZChzKQpyZXR1cm4gdH19ClAuZVkucHJvdG90eXBlPXsKZ0w6ZnVuY3Rpb24oKXtyZXR1cm4iUmFu
-Z2VFcnJvciJ9LApndTpmdW5jdGlvbigpe3ZhciB0LHM9SC5XWSh0aGlzLmIpCmlmKHR5cGVvZiBzIT09
-Im51bWJlciIpcmV0dXJuIHMuSigpCmlmKHM8MClyZXR1cm4iOiBpbmRleCBtdXN0IG5vdCBiZSBuZWdh
-dGl2ZSIKdD10aGlzLmYKaWYodD09PTApcmV0dXJuIjogbm8gaW5kaWNlcyBhcmUgdmFsaWQiCnJldHVy
-biI6IGluZGV4IHNob3VsZCBiZSBsZXNzIHRoYW4gIitILmQodCl9LApnQTpmdW5jdGlvbihhKXtyZXR1
-cm4gdGhpcy5mfX0KUC5tcC5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAsbyxu
-LG0sbD10aGlzLGs9e30saj1uZXcgUC5SbigiIikKay5hPSIiCnQ9bC5jCmZvcihzPXQubGVuZ3RoLHI9
-MCxxPSIiLHA9IiI7cjxzOysrcixwPSIsICIpe289dFtyXQpqLmE9cStwCnE9ai5hKz1QLmgobykKay5h
-PSIsICJ9bC5kLksoMCxuZXcgUC5XRihrLGopKQpuPVAuaChsLmEpCm09ai5aKDApCnM9Ik5vU3VjaE1l
-dGhvZEVycm9yOiBtZXRob2Qgbm90IGZvdW5kOiAnIitILmQobC5iLmEpKyInXG5SZWNlaXZlcjogIitu
-KyJcbkFyZ3VtZW50czogWyIrbSsiXSIKcmV0dXJuIHN9fQpQLnViLnByb3RvdHlwZT17Clo6ZnVuY3Rp
-b24oYSl7cmV0dXJuIlVuc3VwcG9ydGVkIG9wZXJhdGlvbjogIit0aGlzLmF9fQpQLmRzLnByb3RvdHlw
-ZT17Clo6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCnJldHVybiB0IT1udWxsPyJVbmltcGxlbWVudGVk
-RXJyb3I6ICIrdDoiVW5pbXBsZW1lbnRlZEVycm9yIn19ClAubGoucHJvdG90eXBlPXsKWjpmdW5jdGlv
-bihhKXtyZXR1cm4iQmFkIHN0YXRlOiAiK3RoaXMuYX19ClAuVVYucHJvdG90eXBlPXsKWjpmdW5jdGlv
-bihhKXt2YXIgdD10aGlzLmEKaWYodD09bnVsbClyZXR1cm4iQ29uY3VycmVudCBtb2RpZmljYXRpb24g
-ZHVyaW5nIGl0ZXJhdGlvbi4iCnJldHVybiJDb25jdXJyZW50IG1vZGlmaWNhdGlvbiBkdXJpbmcgaXRl
-cmF0aW9uOiAiK1AuaCh0KSsiLiJ9fQpQLms1LnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7cmV0dXJu
-Ik91dCBvZiBNZW1vcnkifSwKZ0lJOmZ1bmN0aW9uKCl7cmV0dXJuIG51bGx9LAokaVhTOjF9ClAuS1ku
-cHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXtyZXR1cm4iU3RhY2sgT3ZlcmZsb3cifSwKZ0lJOmZ1bmN0
-aW9uKCl7cmV0dXJuIG51bGx9LAokaVhTOjF9ClAudDcucHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXt2
-YXIgdD10aGlzLmEKcmV0dXJuIHQ9PW51bGw/IlJlYWRpbmcgc3RhdGljIHZhcmlhYmxlIGR1cmluZyBp
-dHMgaW5pdGlhbGl6YXRpb24iOiJSZWFkaW5nIHN0YXRpYyB2YXJpYWJsZSAnIit0KyInIGR1cmluZyBp
-dHMgaW5pdGlhbGl6YXRpb24ifX0KUC5DRC5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3JldHVybiJF
-eGNlcHRpb246ICIrdGhpcy5hfX0KUC5hRS5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3ZhciB0LHMs
-cixxLHAsbyxuLG0sbCxrLGosaSxoPXRoaXMuYSxnPWghPW51bGwmJiIiIT09aD8iRm9ybWF0RXhjZXB0
-aW9uOiAiK0guZChoKToiRm9ybWF0RXhjZXB0aW9uIixmPXRoaXMuYyxlPXRoaXMuYgppZih0eXBlb2Yg
-ZT09InN0cmluZyIpe2lmKGYhPW51bGwpdD1mPDB8fGY+ZS5sZW5ndGgKZWxzZSB0PSExCmlmKHQpZj1u
-dWxsCmlmKGY9PW51bGwpe2lmKGUubGVuZ3RoPjc4KWU9Qy54Qi5OaihlLDAsNzUpKyIuLi4iCnJldHVy
-biBnKyJcbiIrZX1mb3Iocz0xLHI9MCxxPSExLHA9MDtwPGY7KytwKXtvPUMueEIuVyhlLHApCmlmKG89
-PT0xMCl7aWYociE9PXB8fCFxKSsrcwpyPXArMQpxPSExfWVsc2UgaWYobz09PTEzKXsrK3MKcj1wKzEK
-cT0hMH19Zz1zPjE/ZysoIiAoYXQgbGluZSAiK3MrIiwgY2hhcmFjdGVyICIrKGYtcisxKSsiKVxuIik6
-ZysoIiAoYXQgY2hhcmFjdGVyICIrKGYrMSkrIilcbiIpCm49ZS5sZW5ndGgKZm9yKHA9ZjtwPG47Kytw
-KXtvPUMueEIubShlLHApCmlmKG89PT0xMHx8bz09PTEzKXtuPXAKYnJlYWt9fWlmKG4tcj43OClpZihm
-LXI8NzUpe209cis3NQpsPXIKaz0iIgpqPSIuLi4ifWVsc2V7aWYobi1mPDc1KXtsPW4tNzUKbT1uCmo9
-IiJ9ZWxzZXtsPWYtMzYKbT1mKzM2Cmo9Ii4uLiJ9az0iLi4uIn1lbHNle209bgpsPXIKaz0iIgpqPSIi
-fWk9Qy54Qi5OaihlLGwsbSkKcmV0dXJuIGcraytpK2orIlxuIitDLnhCLkl4KCIgIixmLWwray5sZW5n
-dGgpKyJeXG4ifWVsc2UgcmV0dXJuIGYhPW51bGw/ZysoIiAoYXQgb2Zmc2V0ICIrSC5kKGYpKyIpIik6
-Z319ClAuRUgucHJvdG90eXBlPXt9ClAuSWYucHJvdG90eXBlPXt9ClAuY1gucHJvdG90eXBlPXsKRTI6
-ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PUguTGgodGhpcykKcmV0dXJuIEguSzEodGhpcyx0LktxKGMpLkMo
-IjEoY1guRSkiKS5hKGIpLHQuQygiY1guRSIpLGMpfSwKZXY6ZnVuY3Rpb24oYSxiKXt2YXIgdD1ILkxo
-KHRoaXMpCnJldHVybiBuZXcgSC5VNSh0aGlzLHQuQygiYTIoY1guRSkiKS5hKGIpLHQuQygiVTU8Y1gu
-RT4iKSl9LApnQTpmdW5jdGlvbihhKXt2YXIgdCxzPXRoaXMuZ2t6KHRoaXMpCmZvcih0PTA7cy5GKCk7
-KSsrdApyZXR1cm4gdH0sCmdsMDpmdW5jdGlvbihhKXtyZXR1cm4hdGhpcy5na3oodGhpcykuRigpfSwK
-Z3I4OmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcy5na3oodGhpcykKaWYoIXMuRigpKXRocm93IEguYihI
-LldwKCkpCnQ9cy5nbCgpCmlmKHMuRigpKXRocm93IEguYihILmRVKCkpCnJldHVybiB0fSwKRTpmdW5j
-dGlvbihhLGIpe3ZhciB0LHMscgpQLmsxKGIsImluZGV4IikKZm9yKHQ9dGhpcy5na3oodGhpcykscz0w
-O3QuRigpOyl7cj10LmdsKCkKaWYoYj09PXMpcmV0dXJuIHI7KytzfXRocm93IEguYihQLnQoYix0aGlz
-LCJpbmRleCIsbnVsbCxzKSl9LApaOmZ1bmN0aW9uKGEpe3JldHVybiBQLkVQKHRoaXMsIigiLCIpIil9
-fQpQLkFuLnByb3RvdHlwZT17fQpQLnpNLnByb3RvdHlwZT17JGliUToxLCRpY1g6MX0KUC5aMC5wcm90
-b3R5cGU9e30KUC5OMy5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3JldHVybiJNYXBFbnRyeSgiK0gu
-ZChKLkFjKHRoaXMuYSkpKyI6ICIrSC5kKEouQWModGhpcy5iKSkrIikifX0KUC5jOC5wcm90b3R5cGU9
-ewpnaU86ZnVuY3Rpb24oYSl7cmV0dXJuIFAuTWgucHJvdG90eXBlLmdpTy5jYWxsKHRoaXMsdGhpcyl9
-LApaOmZ1bmN0aW9uKGEpe3JldHVybiJudWxsIn19ClAubGYucHJvdG90eXBlPXt9ClAuTWgucHJvdG90
-eXBlPXtjb25zdHJ1Y3RvcjpQLk1oLCRpTWg6MSwKRE46ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcz09
-PWJ9LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJuIEguZVEodGhpcyl9LApaOmZ1bmN0aW9uKGEpe3JldHVy
-biJJbnN0YW5jZSBvZiAnIitILmQoSC5saCh0aGlzKSkrIicifSwKZTc6ZnVuY3Rpb24oYSxiKXt1Lm8u
-YShiKQp0aHJvdyBILmIoUC5scih0aGlzLGIuZ1dhKCksYi5nbmQoKSxiLmdWbSgpKSl9LAp0b1N0cmlu
-ZzpmdW5jdGlvbigpe3JldHVybiB0aGlzLloodGhpcyl9fQpQLk9kLnByb3RvdHlwZT17fQpQLmliLnBy
-b3RvdHlwZT17JGlPZDoxfQpQLnh1LnByb3RvdHlwZT17fQpQLkd6LnByb3RvdHlwZT17fQpQLlpkLnBy
-b3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7cmV0dXJuIiJ9LAokaUd6OjF9ClAucVUucHJvdG90eXBlPXsk
-aXZYOjF9ClAuUm4ucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5sZW5ndGh9
-LApaOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYQpyZXR1cm4gdC5jaGFyQ29kZUF0KDApPT0wP3Q6dH0s
-CiRpQkw6MX0KUC5HRC5wcm90b3R5cGU9e30KUC5uMS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIp
-e3ZhciB0LHMscixxCnUuZi5hKGEpCkguYyhiKQp0PUouclkoYikuT1koYiwiPSIpCmlmKHQ9PT0tMSl7
-aWYoYiE9PSIiKWEuWSgwLFAua3UoYiwwLGIubGVuZ3RoLHRoaXMuYSwhMCksIiIpfWVsc2UgaWYodCE9
-PTApe3M9Qy54Qi5OaihiLDAsdCkKcj1DLnhCLkcoYix0KzEpCnE9dGhpcy5hCmEuWSgwLFAua3Uocyww
-LHMubGVuZ3RoLHEsITApLFAua3UociwwLHIubGVuZ3RoLHEsITApKX1yZXR1cm4gYX0sCiRTOjE5fQpQ
-LmNTLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dGhyb3cgSC5iKFAucnIoIklsbGVnYWwgSVB2
-NCBhZGRyZXNzLCAiK2EsdGhpcy5hLGIpKX0sCiRTOjQ3fQpQLlZDLnByb3RvdHlwZT17CiQyOmZ1bmN0
-aW9uKGEsYil7dGhyb3cgSC5iKFAucnIoIklsbGVnYWwgSVB2NiBhZGRyZXNzLCAiK2EsdGhpcy5hLGIp
-KX0sCiQxOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLiQyKGEsbnVsbCl9LAokUzo0OH0KUC5KVC5wcm90
-b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciB0CmlmKGItYT40KXRoaXMuYS4kMigiYW4gSVB2NiBw
-YXJ0IGNhbiBvbmx5IGNvbnRhaW4gYSBtYXhpbXVtIG9mIDQgaGV4IGRpZ2l0cyIsYSkKdD1QLlFBKEMu
-eEIuTmoodGhpcy5iLGEsYiksMTYpCmlmKHR5cGVvZiB0IT09Im51bWJlciIpcmV0dXJuIHQuSigpCmlm
-KHQ8MHx8dD42NTUzNSl0aGlzLmEuJDIoImVhY2ggcGFydCBtdXN0IGJlIGluIHRoZSByYW5nZSBvZiBg
-MHgwLi4weEZGRkZgIixhKQpyZXR1cm4gdH0sCiRTOjIwfQpQLkRuLnByb3RvdHlwZT17CmduRDpmdW5j
-dGlvbigpe3ZhciB0LHMscixxPXRoaXMscD1xLngKaWYocD09bnVsbCl7cD1xLmEKdD1wLmxlbmd0aCE9
-PTA/cCsiOiI6IiIKcz1xLmMKcj1zPT1udWxsCmlmKCFyfHxwPT09ImZpbGUiKXtwPXQrIi8vIgp0PXEu
-YgppZih0Lmxlbmd0aCE9PTApcD1wK3QrIkAiCmlmKCFyKXArPXMKdD1xLmQKaWYodCE9bnVsbClwPXAr
-IjoiK0guZCh0KX1lbHNlIHA9dApwKz1xLmUKdD1xLmYKaWYodCE9bnVsbClwPXArIj8iK3QKdD1xLnIK
-aWYodCE9bnVsbClwPXArIiMiK3QKcD1wLmNoYXJDb2RlQXQoMCk9PTA/cDpwCmlmKHEueD09bnVsbClx
-Lng9cAplbHNlIHA9SC52aChILnlSKCJGaWVsZCAnX3RleHQnIGhhcyBiZWVuIGFzc2lnbmVkIGR1cmlu
-ZyBpbml0aWFsaXphdGlvbi4iKSl9cmV0dXJuIHB9LApnRmo6ZnVuY3Rpb24oKXt2YXIgdCxzPXRoaXMs
-cj1zLnkKaWYocj09bnVsbCl7dD1zLmUKaWYodC5sZW5ndGghPT0wJiZDLnhCLlcodCwwKT09PTQ3KXQ9
-Qy54Qi5HKHQsMSkKcj10Lmxlbmd0aD09PTA/Qy54RDpQLkFGKG5ldyBILmxKKEguVk0odC5zcGxpdCgi
-LyIpLHUucyksdS5kTy5hKFAuUEgoKSksdS5kbyksdS5OKQppZihzLnk9PW51bGwpcy5zS3AocikKZWxz
-ZSByPUgudmgoSC55UigiRmllbGQgJ3BhdGhTZWdtZW50cycgaGFzIGJlZW4gYXNzaWduZWQgZHVyaW5n
-IGluaXRpYWxpemF0aW9uLiIpKX1yZXR1cm4gcn0sCmdpTzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLHM9
-dC56CmlmKHM9PW51bGwpe3M9Qy54Qi5naU8odC5nbkQoKSkKaWYodC56PT1udWxsKXQuej1zCmVsc2Ug
-cz1ILnZoKEgueVIoIkZpZWxkICdoYXNoQ29kZScgaGFzIGJlZW4gYXNzaWduZWQgZHVyaW5nIGluaXRp
-YWxpemF0aW9uLiIpKX1yZXR1cm4gc30sCmdoWTpmdW5jdGlvbigpe3ZhciB0PXRoaXMscz10LlEKaWYo
-cz09bnVsbCl7cz1uZXcgUC5HaihQLldYKHQuZ3RQKCkpLHUuRCkKaWYodC5RPT1udWxsKXQuc05NKHMp
-CmVsc2Ugcz1ILnZoKEgueVIoIkZpZWxkICdxdWVyeVBhcmFtZXRlcnMnIGhhcyBiZWVuIGFzc2lnbmVk
-IGR1cmluZyBpbml0aWFsaXphdGlvbi4iKSl9cmV0dXJuIHN9LApna3U6ZnVuY3Rpb24oKXtyZXR1cm4g
-dGhpcy5ifSwKZ0pmOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYwppZih0PT1udWxsKXJldHVybiIiCmlm
-KEMueEIubih0LCJbIikpcmV0dXJuIEMueEIuTmoodCwxLHQubGVuZ3RoLTEpCnJldHVybiB0fSwKZ3Rw
-OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuZApyZXR1cm4gdD09bnVsbD9QLndLKHRoaXMuYSk6dH0sCmd0
-UDpmdW5jdGlvbigpe3ZhciB0PXRoaXMuZgpyZXR1cm4gdD09bnVsbD8iIjp0fSwKZ0thOmZ1bmN0aW9u
-KCl7dmFyIHQ9dGhpcy5yCnJldHVybiB0PT1udWxsPyIiOnR9LApubTpmdW5jdGlvbihhLGIpe3ZhciB0
-LHMscixxLHAsbyxuLG0sbCxrPXRoaXMKdS5YLmEobnVsbCkKdS5iLmEoYikKdD1rLmEKcz10PT09ImZp
-bGUiCnI9ay5iCnE9ay5kCnA9ay5jCmlmKCEocCE9bnVsbCkpcD1yLmxlbmd0aCE9PTB8fHEhPW51bGx8
-fHM/IiI6bnVsbApvPWsuZQppZighcyluPXAhPW51bGwmJm8ubGVuZ3RoIT09MAplbHNlIG49ITAKaWYo
-biYmIUMueEIubihvLCIvIikpbz0iLyIrbwptPW8KbD1QLmxlKG51bGwsMCwwLGIpCnJldHVybiBuZXcg
-UC5Ebih0LHIscCxxLG0sbCxrLnIpfSwKSmg6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG8KZm9y
-KHQ9MCxzPTA7Qy54Qi5RaShiLCIuLi8iLHMpOyl7cys9MzsrK3R9cj1DLnhCLmNuKGEsIi8iKQp3aGls
-ZSghMCl7aWYoIShyPjAmJnQ+MCkpYnJlYWsKcT1DLnhCLlBrKGEsIi8iLHItMSkKaWYocTwwKWJyZWFr
-CnA9ci1xCm89cCE9PTIKaWYoIW98fHA9PT0zKWlmKEMueEIubShhLHErMSk9PT00NilvPSFvfHxDLnhC
-Lm0oYSxxKzIpPT09NDYKZWxzZSBvPSExCmVsc2Ugbz0hMQppZihvKWJyZWFrOy0tdApyPXF9cmV0dXJu
-IEMueEIuaTcoYSxyKzEsbnVsbCxDLnhCLkcoYixzLTMqdCkpfSwKWkk6ZnVuY3Rpb24oYSl7cmV0dXJu
-IHRoaXMubVMoUC5oSyhhKSl9LAptUzpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsaz10
-aGlzLGo9bnVsbAppZihhLmdGaSgpLmxlbmd0aCE9PTApe3Q9YS5nRmkoKQppZihhLmdjaigpKXtzPWEu
-Z2t1KCkKcj1hLmdKZihhKQpxPWEuZ3hBKCk/YS5ndHAoYSk6an1lbHNle3E9agpyPXEKcz0iIn1wPVAu
-eGUoYS5nSWkoYSkpCm89YS5nUUQoKT9hLmd0UCgpOmp9ZWxzZXt0PWsuYQppZihhLmdjaigpKXtzPWEu
-Z2t1KCkKcj1hLmdKZihhKQpxPVAud0IoYS5neEEoKT9hLmd0cChhKTpqLHQpCnA9UC54ZShhLmdJaShh
-KSkKbz1hLmdRRCgpP2EuZ3RQKCk6an1lbHNle3M9ay5iCnI9ay5jCnE9ay5kCmlmKGEuZ0lpKGEpPT09
-IiIpe3A9ay5lCm89YS5nUUQoKT9hLmd0UCgpOmsuZn1lbHNle2lmKGEuZ3RUKCkpcD1QLnhlKGEuZ0lp
-KGEpKQplbHNle249ay5lCmlmKG4ubGVuZ3RoPT09MClpZihyPT1udWxsKXA9dC5sZW5ndGg9PT0wP2Eu
-Z0lpKGEpOlAueGUoYS5nSWkoYSkpCmVsc2UgcD1QLnhlKCIvIithLmdJaShhKSkKZWxzZXttPWsuSmgo
-bixhLmdJaShhKSkKbD10Lmxlbmd0aD09PTAKaWYoIWx8fHIhPW51bGx8fEMueEIubihuLCIvIikpcD1Q
-LnhlKG0pCmVsc2UgcD1QLndGKG0sIWx8fHIhPW51bGwpfX1vPWEuZ1FEKCk/YS5ndFAoKTpqfX19cmV0
-dXJuIG5ldyBQLkRuKHQscyxyLHEscCxvLGEuZ1o4KCk/YS5nS2EoKTpqKX0sCmdjajpmdW5jdGlvbigp
-e3JldHVybiB0aGlzLmMhPW51bGx9LApneEE6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kIT1udWxsfSwK
-Z1FEOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZiE9bnVsbH0sCmdaODpmdW5jdGlvbigpe3JldHVybiB0
-aGlzLnIhPW51bGx9LApndFQ6ZnVuY3Rpb24oKXtyZXR1cm4gQy54Qi5uKHRoaXMuZSwiLyIpfSwKdDQ6
-ZnVuY3Rpb24oKXt2YXIgdCxzPXRoaXMscj1zLmEKaWYociE9PSIiJiZyIT09ImZpbGUiKXRocm93IEgu
-YihQLkw0KCJDYW5ub3QgZXh0cmFjdCBhIGZpbGUgcGF0aCBmcm9tIGEgIityKyIgVVJJIikpCmlmKHMu
-Z3RQKCkhPT0iIil0aHJvdyBILmIoUC5MNCgiQ2Fubm90IGV4dHJhY3QgYSBmaWxlIHBhdGggZnJvbSBh
-IFVSSSB3aXRoIGEgcXVlcnkgY29tcG9uZW50IikpCmlmKHMuZ0thKCkhPT0iIil0aHJvdyBILmIoUC5M
-NCgiQ2Fubm90IGV4dHJhY3QgYSBmaWxlIHBhdGggZnJvbSBhIFVSSSB3aXRoIGEgZnJhZ21lbnQgY29t
-cG9uZW50IikpCnI9JC5PeCgpCmlmKEgub1Qocikpcj1QLm1uKHMpCmVsc2V7aWYocy5jIT1udWxsJiZz
-LmdKZihzKSE9PSIiKUgudmgoUC5MNCgiQ2Fubm90IGV4dHJhY3QgYSBub24tV2luZG93cyBmaWxlIHBh
-dGggZnJvbSBhIGZpbGUgVVJJIHdpdGggYW4gYXV0aG9yaXR5IikpCnQ9cy5nRmooKQpQLmtFKHQsITEp
-CnI9UC52ZyhDLnhCLm4ocy5lLCIvIik/Ii8iOiIiLHQsIi8iKQpyPXIuY2hhckNvZGVBdCgwKT09MD9y
-OnJ9cmV0dXJuIHJ9LApaOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmduRCgpfSwKRE46ZnVuY3Rpb24o
-YSxiKXt2YXIgdD10aGlzCmlmKGI9PW51bGwpcmV0dXJuITEKaWYodD09PWIpcmV0dXJuITAKcmV0dXJu
-IHUuRi5iKGIpJiZ0LmE9PT1iLmdGaSgpJiZ0LmMhPW51bGw9PT1iLmdjaigpJiZ0LmI9PT1iLmdrdSgp
-JiZ0LmdKZih0KT09PWIuZ0pmKGIpJiZ0Lmd0cCh0KT09PWIuZ3RwKGIpJiZ0LmU9PT1iLmdJaShiKSYm
-dC5mIT1udWxsPT09Yi5nUUQoKSYmdC5ndFAoKT09PWIuZ3RQKCkmJnQuciE9bnVsbD09PWIuZ1o4KCkm
-JnQuZ0thKCk9PT1iLmdLYSgpfSwKc0twOmZ1bmN0aW9uKGEpe3RoaXMueT11LmEuYShhKX0sCnNOTTpm
-dW5jdGlvbihhKXt0aGlzLlE9dS5mLmEoYSl9LAokaWlEOjEsCmdGaTpmdW5jdGlvbigpe3JldHVybiB0
-aGlzLmF9LApnSWk6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZX19ClAuUloucHJvdG90eXBlPXsKJDE6
-ZnVuY3Rpb24oYSl7cmV0dXJuIFAuZVAoQy5aSixILmMoYSksQy54TSwhMSl9LAokUzo0fQpQLk1FLnBy
-b3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHQ9dGhpcy5iLHM9dGhpcy5hCnQuYSs9cy5hCnMu
-YT0iJiIKcz10LmErPUguZChQLmVQKEMuRjMsYSxDLnhNLCEwKSkKaWYoYiE9bnVsbCYmYi5sZW5ndGgh
-PT0wKXt0LmE9cysiPSIKdC5hKz1ILmQoUC5lUChDLkYzLGIsQy54TSwhMCkpfX0sCiRTOjIyfQpQLnk1
-LnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHQscwpILmMoYSkKaWYoYj09bnVsbHx8dHlw
-ZW9mIGI9PSJzdHJpbmciKXRoaXMuYS4kMihhLEguYyhiKSkKZWxzZSBmb3IodD1KLklUKHUuUi5hKGIp
-KSxzPXRoaXMuYTt0LkYoKTspcy4kMihhLEguYyh0LmdsKCkpKX0sCiRTOjEzfQpQLlBFLnByb3RvdHlw
+KXt0PWIueAppZih0IT1udWxsKXJldHVybiB0fXJldHVybiB1LmFVLmIoYSl9LApFajpmdW5jdGlvbihh
+KXt2YXIgdAppZih0eXBlb2YgYT09InN0cmluZyIpcmV0dXJuIGEKaWYodHlwZW9mIGE9PSJudW1iZXIi
+KXtpZihhIT09MClyZXR1cm4iIithfWVsc2UgaWYoITA9PT1hKXJldHVybiJ0cnVlIgplbHNlIGlmKCEx
+PT09YSlyZXR1cm4iZmFsc2UiCmVsc2UgaWYoYT09bnVsbClyZXR1cm4ibnVsbCIKdD1KLmooYSkKaWYo
+dHlwZW9mIHQhPSJzdHJpbmciKXRocm93IEguYihILnRMKGEpKQpyZXR1cm4gdH0sCmVROmZ1bmN0aW9u
+KGEpe3ZhciB0PWEuJGlkZW50aXR5SGFzaAppZih0PT1udWxsKXt0PU1hdGgucmFuZG9tKCkqMHgzZmZm
+ZmZmZnwwCmEuJGlkZW50aXR5SGFzaD10fXJldHVybiB0fSwKSHA6ZnVuY3Rpb24oYSxiKXt2YXIgdCxz
+LHIscSxwLG8sbj1udWxsCmlmKHR5cGVvZiBhIT0ic3RyaW5nIilILnZoKEgudEwoYSkpCnQ9L15ccypb
+Ky1dPygoMHhbYS1mMC05XSspfChcZCspfChbYS16MC05XSspKVxzKiQvaS5leGVjKGEpCmlmKHQ9PW51
+bGwpcmV0dXJuIG4KaWYoMz49dC5sZW5ndGgpcmV0dXJuIEguT0godCwzKQpzPUguaCh0WzNdKQppZihi
+PT1udWxsKXtpZihzIT1udWxsKXJldHVybiBwYXJzZUludChhLDEwKQppZih0WzJdIT1udWxsKXJldHVy
+biBwYXJzZUludChhLDE2KQpyZXR1cm4gbn1pZihiPDJ8fGI+MzYpdGhyb3cgSC5iKFAuVEUoYiwyLDM2
+LCJyYWRpeCIsbikpCmlmKGI9PT0xMCYmcyE9bnVsbClyZXR1cm4gcGFyc2VJbnQoYSwxMCkKaWYoYjwx
+MHx8cz09bnVsbCl7cj1iPD0xMD80NytiOjg2K2IKcT10WzFdCmZvcihwPXEubGVuZ3RoLG89MDtvPHA7
+KytvKWlmKChDLnhCLlcocSxvKXwzMik+cilyZXR1cm4gbn1yZXR1cm4gcGFyc2VJbnQoYSxiKX0sCk06
+ZnVuY3Rpb24oYSl7dmFyIHQ9SC5INShhKQpyZXR1cm4gdH0sCkg1OmZ1bmN0aW9uKGEpe3ZhciB0LHMs
+cgppZihhIGluc3RhbmNlb2YgUC5NaClyZXR1cm4gSC5kbShILnooYSksbnVsbCkKaWYoSi5pYShhKT09
+PUMuT2t8fHUuYWsuYihhKSl7dD1DLk80KGEpCmlmKEguQmUodCkpcmV0dXJuIHQKcz1hLmNvbnN0cnVj
+dG9yCmlmKHR5cGVvZiBzPT0iZnVuY3Rpb24iKXtyPXMubmFtZQppZih0eXBlb2Ygcj09InN0cmluZyIm
+JkguQmUocikpcmV0dXJuIHJ9fXJldHVybiBILmRtKEgueihhKSxudWxsKX0sCkJlOmZ1bmN0aW9uKGEp
+e3ZhciB0PWEhPT0iT2JqZWN0IiYmYSE9PSIiCnJldHVybiB0fSwKTTA6ZnVuY3Rpb24oKXtpZighIXNl
+bGYubG9jYXRpb24pcmV0dXJuIHNlbGYubG9jYXRpb24uaHJlZgpyZXR1cm4gbnVsbH0sClZLOmZ1bmN0
+aW9uKGEpe3ZhciB0LHMscixxLHA9YS5sZW5ndGgKaWYocDw9NTAwKXJldHVybiBTdHJpbmcuZnJvbUNo
+YXJDb2RlLmFwcGx5KG51bGwsYSkKZm9yKHQ9IiIscz0wO3M8cDtzPXIpe3I9cys1MDAKcT1yPHA/cjpw
+CnQrPVN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCxhLnNsaWNlKHMscSkpfXJldHVybiB0fSwK
+Q3E6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHE9SC5WTShbXSx1LnQpCmZvcih0PWEubGVuZ3RoLHM9MDtz
+PGEubGVuZ3RoO2EubGVuZ3RoPT09dHx8KDAsSC5saykoYSksKytzKXtyPWFbc10KaWYoIUgub2socikp
+dGhyb3cgSC5iKEgudEwocikpCmlmKHI8PTY1NTM1KUMuTm0uaShxLHIpCmVsc2UgaWYocjw9MTExNDEx
+MSl7Qy5ObS5pKHEsNTUyOTYrKEMuam4ud0coci02NTUzNiwxMCkmMTAyMykpCkMuTm0uaShxLDU2MzIw
+KyhyJjEwMjMpKX1lbHNlIHRocm93IEguYihILnRMKHIpKX1yZXR1cm4gSC5WSyhxKX0sCmVUOmZ1bmN0
+aW9uKGEpe3ZhciB0LHMscgpmb3IodD1hLmxlbmd0aCxzPTA7czx0Oysrcyl7cj1hW3NdCmlmKCFILm9r
+KHIpKXRocm93IEguYihILnRMKHIpKQppZihyPDApdGhyb3cgSC5iKEgudEwocikpCmlmKHI+NjU1MzUp
+cmV0dXJuIEguQ3EoYSl9cmV0dXJuIEguVksoYSl9LApmdzpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxy
+LHEKaWYoYzw9NTAwJiZiPT09MCYmYz09PWEubGVuZ3RoKXJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2Rl
+LmFwcGx5KG51bGwsYSkKZm9yKHQ9YixzPSIiO3Q8Yzt0PXIpe3I9dCs1MDAKcT1yPGM/cjpjCnMrPVN0
+cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCxhLnN1YmFycmF5KHQscSkpfXJldHVybiBzfSwKTHc6
+ZnVuY3Rpb24oYSl7dmFyIHQKaWYoMDw9YSl7aWYoYTw9NjU1MzUpcmV0dXJuIFN0cmluZy5mcm9tQ2hh
+ckNvZGUoYSkKaWYoYTw9MTExNDExMSl7dD1hLTY1NTM2CnJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2Rl
+KCg1NTI5NnxDLmpuLndHKHQsMTApKT4+PjAsNTYzMjB8dCYxMDIzKX19dGhyb3cgSC5iKFAuVEUoYSww
+LDExMTQxMTEsbnVsbCxudWxsKSl9LApvMjpmdW5jdGlvbihhKXtpZihhLmRhdGU9PT12b2lkIDApYS5k
+YXRlPW5ldyBEYXRlKGEuYSkKcmV0dXJuIGEuZGF0ZX0sCnRKOmZ1bmN0aW9uKGEpe3ZhciB0PUgubzIo
+YSkuZ2V0RnVsbFllYXIoKSswCnJldHVybiB0fSwKTlM6ZnVuY3Rpb24oYSl7dmFyIHQ9SC5vMihhKS5n
+ZXRNb250aCgpKzEKcmV0dXJuIHR9LApqQTpmdW5jdGlvbihhKXt2YXIgdD1ILm8yKGEpLmdldERhdGUo
+KSswCnJldHVybiB0fSwKSVg6ZnVuY3Rpb24oYSl7dmFyIHQ9SC5vMihhKS5nZXRIb3VycygpKzAKcmV0
+dXJuIHR9LApjaDpmdW5jdGlvbihhKXt2YXIgdD1ILm8yKGEpLmdldE1pbnV0ZXMoKSswCnJldHVybiB0
+fSwKSmQ6ZnVuY3Rpb24oYSl7dmFyIHQ9SC5vMihhKS5nZXRTZWNvbmRzKCkrMApyZXR1cm4gdH0sCm8x
+OmZ1bmN0aW9uKGEpe3ZhciB0PUgubzIoYSkuZ2V0TWlsbGlzZWNvbmRzKCkrMApyZXR1cm4gdH0sCnpv
+OmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHI9e30Kci5hPTAKdD1bXQpzPVtdCnIuYT1iLmxlbmd0aApD
+Lk5tLkZWKHQsYikKci5iPSIiCmlmKGMhPW51bGwmJmMuYSE9PTApYy5LKDAsbmV3IEguQ2oocixzLHQp
+KQoiIityLmEKcmV0dXJuIEouSnkoYSxuZXcgSC5MSShDLlRlLDAsdCxzLDApKX0sCkVrOmZ1bmN0aW9u
+KGEsYixjKXt2YXIgdCxzLHIscQppZihiIGluc3RhbmNlb2YgQXJyYXkpdD1jPT1udWxsfHxjLmE9PT0w
+CmVsc2UgdD0hMQppZih0KXtzPWIKcj1zLmxlbmd0aAppZihyPT09MCl7aWYoISFhLiQwKXJldHVybiBh
+LiQwKCl9ZWxzZSBpZihyPT09MSl7aWYoISFhLiQxKXJldHVybiBhLiQxKHNbMF0pfWVsc2UgaWYocj09
+PTIpe2lmKCEhYS4kMilyZXR1cm4gYS4kMihzWzBdLHNbMV0pfWVsc2UgaWYocj09PTMpe2lmKCEhYS4k
+MylyZXR1cm4gYS4kMyhzWzBdLHNbMV0sc1syXSl9ZWxzZSBpZihyPT09NCl7aWYoISFhLiQ0KXJldHVy
+biBhLiQ0KHNbMF0sc1sxXSxzWzJdLHNbM10pfWVsc2UgaWYocj09PTUpaWYoISFhLiQ1KXJldHVybiBh
+LiQ1KHNbMF0sc1sxXSxzWzJdLHNbM10sc1s0XSkKcT1hWyIiKyIkIityXQppZihxIT1udWxsKXJldHVy
+biBxLmFwcGx5KGEscyl9cmV0dXJuIEguZTEoYSxiLGMpfSwKZTE6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0
+LHMscixxLHAsbyxuLG0sbCxrPWIgaW5zdGFuY2VvZiBBcnJheT9iOlAuQ0goYiwhMCx1LnopLGo9ay5s
+ZW5ndGgsaT1hLiRSCmlmKGo8aSlyZXR1cm4gSC56byhhLGssYykKdD1hLiRECnM9dD09bnVsbApyPSFz
+P3QoKTpudWxsCnE9Si5pYShhKQpwPXEuJEMKaWYodHlwZW9mIHA9PSJzdHJpbmciKXA9cVtwXQppZihz
+KXtpZihjIT1udWxsJiZjLmEhPT0wKXJldHVybiBILnpvKGEsayxjKQppZihqPT09aSlyZXR1cm4gcC5h
+cHBseShhLGspCnJldHVybiBILnpvKGEsayxjKX1pZihyIGluc3RhbmNlb2YgQXJyYXkpe2lmKGMhPW51
+bGwmJmMuYSE9PTApcmV0dXJuIEguem8oYSxrLGMpCmlmKGo+aStyLmxlbmd0aClyZXR1cm4gSC56byhh
+LGssbnVsbCkKQy5ObS5GVihrLHIuc2xpY2Uoai1pKSkKcmV0dXJuIHAuYXBwbHkoYSxrKX1lbHNle2lm
+KGo+aSlyZXR1cm4gSC56byhhLGssYykKbz1PYmplY3Qua2V5cyhyKQppZihjPT1udWxsKWZvcihzPW8u
+bGVuZ3RoLG49MDtuPG8ubGVuZ3RoO28ubGVuZ3RoPT09c3x8KDAsSC5saykobyksKytuKUMuTm0uaShr
+LHJbSC5oKG9bbl0pXSkKZWxzZXtmb3Iocz1vLmxlbmd0aCxtPTAsbj0wO248by5sZW5ndGg7by5sZW5n
+dGg9PT1zfHwoMCxILmxrKShvKSwrK24pe2w9SC5oKG9bbl0pCmlmKGMueDQobCkpeysrbQpDLk5tLmko
+ayxjLnEoMCxsKSl9ZWxzZSBDLk5tLmkoayxyW2xdKX1pZihtIT09Yy5hKXJldHVybiBILnpvKGEsayxj
+KX1yZXR1cm4gcC5hcHBseShhLGspfX0sCnBZOmZ1bmN0aW9uKGEpe3Rocm93IEguYihILnRMKGEpKX0s
+Ck9IOmZ1bmN0aW9uKGEsYil7aWYoYT09bnVsbClKLkhtKGEpCnRocm93IEguYihILkhZKGEsYikpfSwK
+SFk6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzPSJpbmRleCIKaWYoIUgub2soYikpcmV0dXJuIG5ldyBQLnUo
+ITAsYixzLG51bGwpCnQ9SC51UChKLkhtKGEpKQppZihiPDB8fGI+PXQpcmV0dXJuIFAuQ2YoYixhLHMs
+bnVsbCx0KQpyZXR1cm4gUC5PNyhiLHMpfSwKYXU6ZnVuY3Rpb24oYSxiLGMpe2lmKGE+YylyZXR1cm4g
+UC5URShhLDAsYywic3RhcnQiLG51bGwpCmlmKGIhPW51bGwpaWYoYjxhfHxiPmMpcmV0dXJuIFAuVEUo
+YixhLGMsImVuZCIsbnVsbCkKcmV0dXJuIG5ldyBQLnUoITAsYiwiZW5kIixudWxsKX0sCnRMOmZ1bmN0
+aW9uKGEpe3JldHVybiBuZXcgUC51KCEwLGEsbnVsbCxudWxsKX0sCmI6ZnVuY3Rpb24oYSl7dmFyIHQK
+aWYoYT09bnVsbClhPW5ldyBQLm4oKQp0PW5ldyBFcnJvcigpCnQuZGFydEV4Y2VwdGlvbj1hCmlmKCJk
+ZWZpbmVQcm9wZXJ0eSIgaW4gT2JqZWN0KXtPYmplY3QuZGVmaW5lUHJvcGVydHkodCwibWVzc2FnZSIs
+e2dldDpILnh9KQp0Lm5hbWU9IiJ9ZWxzZSB0LnRvU3RyaW5nPUgueApyZXR1cm4gdH0sCng6ZnVuY3Rp
+b24oKXtyZXR1cm4gSi5qKHRoaXMuZGFydEV4Y2VwdGlvbil9LAp2aDpmdW5jdGlvbihhKXt0aHJvdyBI
+LmIoYSl9LApsazpmdW5jdGlvbihhKXt0aHJvdyBILmIoUC5hNChhKSl9LApjTTpmdW5jdGlvbihhKXt2
+YXIgdCxzLHIscSxwLG8KYT1ILmVBKGEucmVwbGFjZShTdHJpbmcoe30pLCckcmVjZWl2ZXIkJykpCnQ9
+YS5tYXRjaCgvXFxcJFthLXpBLVpdK1xcXCQvZykKaWYodD09bnVsbCl0PUguVk0oW10sdS5zKQpzPXQu
+aW5kZXhPZigiXFwkYXJndW1lbnRzXFwkIikKcj10LmluZGV4T2YoIlxcJGFyZ3VtZW50c0V4cHJcXCQi
+KQpxPXQuaW5kZXhPZigiXFwkZXhwclxcJCIpCnA9dC5pbmRleE9mKCJcXCRtZXRob2RcXCQiKQpvPXQu
+aW5kZXhPZigiXFwkcmVjZWl2ZXJcXCQiKQpyZXR1cm4gbmV3IEguZjkoYS5yZXBsYWNlKG5ldyBSZWdF
+eHAoJ1xcXFxcXCRhcmd1bWVudHNcXFxcXFwkJywnZycpLCcoKD86eHxbXnhdKSopJykucmVwbGFjZShu
+ZXcgUmVnRXhwKCdcXFxcXFwkYXJndW1lbnRzRXhwclxcXFxcXCQnLCdnJyksJygoPzp4fFteeF0pKikn
+KS5yZXBsYWNlKG5ldyBSZWdFeHAoJ1xcXFxcXCRleHByXFxcXFxcJCcsJ2cnKSwnKCg/Onh8W154XSkq
+KScpLnJlcGxhY2UobmV3IFJlZ0V4cCgnXFxcXFxcJG1ldGhvZFxcXFxcXCQnLCdnJyksJygoPzp4fFte
+eF0pKiknKS5yZXBsYWNlKG5ldyBSZWdFeHAoJ1xcXFxcXCRyZWNlaXZlclxcXFxcXCQnLCdnJyksJygo
+Pzp4fFteeF0pKiknKSxzLHIscSxwLG8pfSwKUzc6ZnVuY3Rpb24oYSl7cmV0dXJuIGZ1bmN0aW9uKCRl
+eHByJCl7dmFyICRhcmd1bWVudHNFeHByJD0nJGFyZ3VtZW50cyQnCnRyeXskZXhwciQuJG1ldGhvZCQo
+JGFyZ3VtZW50c0V4cHIkKX1jYXRjaCh0KXtyZXR1cm4gdC5tZXNzYWdlfX0oYSl9LApNajpmdW5jdGlv
+bihhKXtyZXR1cm4gZnVuY3Rpb24oJGV4cHIkKXt0cnl7JGV4cHIkLiRtZXRob2QkfWNhdGNoKHQpe3Jl
+dHVybiB0Lm1lc3NhZ2V9fShhKX0sCklqOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBILlcwKGEsYj09
+bnVsbD9udWxsOmIubWV0aG9kKX0sClQzOmZ1bmN0aW9uKGEsYil7dmFyIHQ9Yj09bnVsbCxzPXQ/bnVs
+bDpiLm1ldGhvZApyZXR1cm4gbmV3IEguYXooYSxzLHQ/bnVsbDpiLnJlY2VpdmVyKX0sClJ1OmZ1bmN0
+aW9uKGEpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZj1udWxsLGU9bmV3IEguQW0oYSkK
+aWYoYT09bnVsbClyZXR1cm4gZgppZihhIGluc3RhbmNlb2YgSC5icSlyZXR1cm4gZS4kMShhLmEpCmlm
+KHR5cGVvZiBhIT09Im9iamVjdCIpcmV0dXJuIGEKaWYoImRhcnRFeGNlcHRpb24iIGluIGEpcmV0dXJu
+IGUuJDEoYS5kYXJ0RXhjZXB0aW9uKQplbHNlIGlmKCEoIm1lc3NhZ2UiIGluIGEpKXJldHVybiBhCnQ9
+YS5tZXNzYWdlCmlmKCJudW1iZXIiIGluIGEmJnR5cGVvZiBhLm51bWJlcj09Im51bWJlciIpe3M9YS5u
+dW1iZXIKcj1zJjY1NTM1CmlmKChDLmpuLndHKHMsMTYpJjgxOTEpPT09MTApc3dpdGNoKHIpe2Nhc2Ug
+NDM4OnJldHVybiBlLiQxKEguVDMoSC5Faih0KSsiIChFcnJvciAiK3IrIikiLGYpKQpjYXNlIDQ0NTpj
+YXNlIDUwMDc6cmV0dXJuIGUuJDEoSC5JaihILkVqKHQpKyIgKEVycm9yICIrcisiKSIsZikpfX1pZihh
+IGluc3RhbmNlb2YgVHlwZUVycm9yKXtxPSQuU24oKQpwPSQubHEoKQpvPSQuTjkoKQpuPSQuaUkoKQpt
+PSQuVU4oKQpsPSQuWmgoKQprPSQuck4oKQokLmMzKCkKaj0kLkhLKCkKaT0kLnIxKCkKaD1xLnFTKHQp
+CmlmKGghPW51bGwpcmV0dXJuIGUuJDEoSC5UMyhILmgodCksaCkpCmVsc2V7aD1wLnFTKHQpCmlmKGgh
+PW51bGwpe2gubWV0aG9kPSJjYWxsIgpyZXR1cm4gZS4kMShILlQzKEguaCh0KSxoKSl9ZWxzZXtoPW8u
+cVModCkKaWYoaD09bnVsbCl7aD1uLnFTKHQpCmlmKGg9PW51bGwpe2g9bS5xUyh0KQppZihoPT1udWxs
+KXtoPWwucVModCkKaWYoaD09bnVsbCl7aD1rLnFTKHQpCmlmKGg9PW51bGwpe2g9bi5xUyh0KQppZiho
+PT1udWxsKXtoPWoucVModCkKaWYoaD09bnVsbCl7aD1pLnFTKHQpCmc9aCE9bnVsbH1lbHNlIGc9ITB9
+ZWxzZSBnPSEwfWVsc2UgZz0hMH1lbHNlIGc9ITB9ZWxzZSBnPSEwfWVsc2UgZz0hMH1lbHNlIGc9ITAK
+aWYoZylyZXR1cm4gZS4kMShILklqKEguaCh0KSxoKSl9fXJldHVybiBlLiQxKG5ldyBILnZWKHR5cGVv
+ZiB0PT0ic3RyaW5nIj90OiIiKSl9aWYoYSBpbnN0YW5jZW9mIFJhbmdlRXJyb3Ipe2lmKHR5cGVvZiB0
+PT0ic3RyaW5nIiYmdC5pbmRleE9mKCJjYWxsIHN0YWNrIikhPT0tMSlyZXR1cm4gbmV3IFAuS1koKQp0
+PWZ1bmN0aW9uKGIpe3RyeXtyZXR1cm4gU3RyaW5nKGIpfWNhdGNoKGQpe31yZXR1cm4gbnVsbH0oYSkK
+cmV0dXJuIGUuJDEobmV3IFAudSghMSxmLGYsdHlwZW9mIHQ9PSJzdHJpbmciP3QucmVwbGFjZSgvXlJh
+bmdlRXJyb3I6XHMqLywiIik6dCkpfWlmKHR5cGVvZiBJbnRlcm5hbEVycm9yPT0iZnVuY3Rpb24iJiZh
+IGluc3RhbmNlb2YgSW50ZXJuYWxFcnJvcilpZih0eXBlb2YgdD09InN0cmluZyImJnQ9PT0idG9vIG11
+Y2ggcmVjdXJzaW9uIilyZXR1cm4gbmV3IFAuS1koKQpyZXR1cm4gYX0sCnRzOmZ1bmN0aW9uKGEpe3Zh
+ciB0CmlmKGEgaW5zdGFuY2VvZiBILmJxKXJldHVybiBhLmIKaWYoYT09bnVsbClyZXR1cm4gbmV3IEgu
+WE8oYSkKdD1hLiRjYWNoZWRUcmFjZQppZih0IT1udWxsKXJldHVybiB0CnJldHVybiBhLiRjYWNoZWRU
+cmFjZT1uZXcgSC5YTyhhKX0sCkI3OmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHE9YS5sZW5ndGgKZm9y
+KHQ9MDt0PHE7dD1yKXtzPXQrMQpyPXMrMQpiLlkoMCxhW3RdLGFbc10pfXJldHVybiBifSwKZnQ6ZnVu
+Y3Rpb24oYSxiLGMsZCxlLGYpe3UuWS5hKGEpCnN3aXRjaChILnVQKGIpKXtjYXNlIDA6cmV0dXJuIGEu
+JDAoKQpjYXNlIDE6cmV0dXJuIGEuJDEoYykKY2FzZSAyOnJldHVybiBhLiQyKGMsZCkKY2FzZSAzOnJl
+dHVybiBhLiQzKGMsZCxlKQpjYXNlIDQ6cmV0dXJuIGEuJDQoYyxkLGUsZil9dGhyb3cgSC5iKG5ldyBQ
+LkNEKCJVbnN1cHBvcnRlZCBudW1iZXIgb2YgYXJndW1lbnRzIGZvciB3cmFwcGVkIGNsb3N1cmUiKSl9
+LAp0UjpmdW5jdGlvbihhLGIpe3ZhciB0CmlmKGE9PW51bGwpcmV0dXJuIG51bGwKdD1hLiRpZGVudGl0
+eQppZighIXQpcmV0dXJuIHQKdD1mdW5jdGlvbihjLGQsZSl7cmV0dXJuIGZ1bmN0aW9uKGYsZyxoLGkp
+e3JldHVybiBlKGMsZCxmLGcsaCxpKX19KGEsYixILmZ0KQphLiRpZGVudGl0eT10CnJldHVybiB0fSwK
+aUE6ZnVuY3Rpb24oYSxiLGMsZCxlLGYsZyl7dmFyIHQscyxyLHEscCxvLG4sbSxsPWJbMF0saz1sLiRj
+YWxsTmFtZSxqPWU/T2JqZWN0LmNyZWF0ZShuZXcgSC56eCgpLmNvbnN0cnVjdG9yLnByb3RvdHlwZSk6
+T2JqZWN0LmNyZWF0ZShuZXcgSC5yVChudWxsLG51bGwsbnVsbCwiIikuY29uc3RydWN0b3IucHJvdG90
+eXBlKQpqLiRpbml0aWFsaXplPWouY29uc3RydWN0b3IKaWYoZSl0PWZ1bmN0aW9uIHN0YXRpY190ZWFy
+X29mZigpe3RoaXMuJGluaXRpYWxpemUoKX0KZWxzZXtzPSQueWoKaWYodHlwZW9mIHMhPT0ibnVtYmVy
+IilyZXR1cm4gcy5oKCkKJC55aj1zKzEKcz1uZXcgRnVuY3Rpb24oImEsYixjLGQiK3MsInRoaXMuJGlu
+aXRpYWxpemUoYSxiLGMsZCIrcysiKSIpCnQ9c31qLmNvbnN0cnVjdG9yPXQKdC5wcm90b3R5cGU9agpp
+ZighZSl7cj1ILmJ4KGEsbCxmKQpyLiRyZWZsZWN0aW9uSW5mbz1kfWVsc2V7ai4kc3RhdGljX25hbWU9
+ZwpyPWx9cT1ILmltKGQsZSxmKQpqLiRTPXEKaltrXT1yCmZvcihwPXIsbz0xO288Yi5sZW5ndGg7Kytv
+KXtuPWJbb10KbT1uLiRjYWxsTmFtZQppZihtIT1udWxsKXtuPWU/bjpILmJ4KGEsbixmKQpqW21dPW59
+aWYobz09PWMpe24uJHJlZmxlY3Rpb25JbmZvPWQKcD1ufX1qLiRDPXAKai4kUj1sLiRSCmouJEQ9bC4k
+RApyZXR1cm4gdH0sCmltOmZ1bmN0aW9uKGEsYixjKXt2YXIgdAppZih0eXBlb2YgYT09Im51bWJlciIp
+cmV0dXJuIGZ1bmN0aW9uKGQsZSl7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIGQoZSl9fShILkJwLGEp
+CmlmKHR5cGVvZiBhPT0ic3RyaW5nIil7aWYoYil0aHJvdyBILmIoIkNhbm5vdCBjb21wdXRlIHNpZ25h
+dHVyZSBmb3Igc3RhdGljIHRlYXJvZmYuIikKdD1jP0guUFc6SC5UbgpyZXR1cm4gZnVuY3Rpb24oZCxl
+KXtyZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gZSh0aGlzLGQpfX0oYSx0KX10aHJvdyBILmIoIkVycm9y
+IGluIGZ1bmN0aW9uVHlwZSBvZiB0ZWFyb2ZmIil9LAp2cTpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdD1I
+LkRWCnN3aXRjaChiPy0xOmEpe2Nhc2UgMDpyZXR1cm4gZnVuY3Rpb24oZSxmKXtyZXR1cm4gZnVuY3Rp
+b24oKXtyZXR1cm4gZih0aGlzKVtlXSgpfX0oYyx0KQpjYXNlIDE6cmV0dXJuIGZ1bmN0aW9uKGUsZil7
+cmV0dXJuIGZ1bmN0aW9uKGcpe3JldHVybiBmKHRoaXMpW2VdKGcpfX0oYyx0KQpjYXNlIDI6cmV0dXJu
+IGZ1bmN0aW9uKGUsZil7cmV0dXJuIGZ1bmN0aW9uKGcsaCl7cmV0dXJuIGYodGhpcylbZV0oZyxoKX19
+KGMsdCkKY2FzZSAzOnJldHVybiBmdW5jdGlvbihlLGYpe3JldHVybiBmdW5jdGlvbihnLGgsaSl7cmV0
+dXJuIGYodGhpcylbZV0oZyxoLGkpfX0oYyx0KQpjYXNlIDQ6cmV0dXJuIGZ1bmN0aW9uKGUsZil7cmV0
+dXJuIGZ1bmN0aW9uKGcsaCxpLGope3JldHVybiBmKHRoaXMpW2VdKGcsaCxpLGopfX0oYyx0KQpjYXNl
+IDU6cmV0dXJuIGZ1bmN0aW9uKGUsZil7cmV0dXJuIGZ1bmN0aW9uKGcsaCxpLGosayl7cmV0dXJuIGYo
+dGhpcylbZV0oZyxoLGksaixrKX19KGMsdCkKZGVmYXVsdDpyZXR1cm4gZnVuY3Rpb24oZSxmKXtyZXR1
+cm4gZnVuY3Rpb24oKXtyZXR1cm4gZS5hcHBseShmKHRoaXMpLGFyZ3VtZW50cyl9fShkLHQpfX0sCmJ4
+OmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscSxwLG8sbgppZihjKXJldHVybiBILkhmKGEsYikKdD1i
+LiRzdHViTmFtZQpzPWIubGVuZ3RoCnI9YVt0XQpxPWI9PW51bGw/cj09bnVsbDpiPT09cgpwPSFxfHxz
+Pj0yNwppZihwKXJldHVybiBILnZxKHMsIXEsdCxiKQppZihzPT09MCl7cT0kLnlqCmlmKHR5cGVvZiBx
+IT09Im51bWJlciIpcmV0dXJuIHEuaCgpCiQueWo9cSsxCm89InNlbGYiK3EKcmV0dXJuIG5ldyBGdW5j
+dGlvbigicmV0dXJuIGZ1bmN0aW9uKCl7dmFyICIrbysiID0gdGhpcy4iK0guRWooSC5vTigpKSsiO3Jl
+dHVybiAiK28rIi4iK0guRWoodCkrIigpO30iKSgpfW49ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6
+Ii5zcGxpdCgiIikuc3BsaWNlKDAscykuam9pbigiLCIpCnE9JC55agppZih0eXBlb2YgcSE9PSJudW1i
+ZXIiKXJldHVybiBxLmgoKQokLnlqPXErMQpuKz1xCnJldHVybiBuZXcgRnVuY3Rpb24oInJldHVybiBm
+dW5jdGlvbigiK24rIil7cmV0dXJuIHRoaXMuIitILkVqKEgub04oKSkrIi4iK0guRWoodCkrIigiK24r
+Iik7fSIpKCl9LApaNDpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdD1ILkRWLHM9SC55Uwpzd2l0Y2goYj8t
+MTphKXtjYXNlIDA6dGhyb3cgSC5iKEguRWYoIkludGVyY2VwdGVkIGZ1bmN0aW9uIHdpdGggbm8gYXJn
+dW1lbnRzLiIpKQpjYXNlIDE6cmV0dXJuIGZ1bmN0aW9uKGUsZixnKXtyZXR1cm4gZnVuY3Rpb24oKXty
+ZXR1cm4gZih0aGlzKVtlXShnKHRoaXMpKX19KGMsdCxzKQpjYXNlIDI6cmV0dXJuIGZ1bmN0aW9uKGUs
+ZixnKXtyZXR1cm4gZnVuY3Rpb24oaCl7cmV0dXJuIGYodGhpcylbZV0oZyh0aGlzKSxoKX19KGMsdCxz
+KQpjYXNlIDM6cmV0dXJuIGZ1bmN0aW9uKGUsZixnKXtyZXR1cm4gZnVuY3Rpb24oaCxpKXtyZXR1cm4g
+Zih0aGlzKVtlXShnKHRoaXMpLGgsaSl9fShjLHQscykKY2FzZSA0OnJldHVybiBmdW5jdGlvbihlLGYs
+Zyl7cmV0dXJuIGZ1bmN0aW9uKGgsaSxqKXtyZXR1cm4gZih0aGlzKVtlXShnKHRoaXMpLGgsaSxqKX19
+KGMsdCxzKQpjYXNlIDU6cmV0dXJuIGZ1bmN0aW9uKGUsZixnKXtyZXR1cm4gZnVuY3Rpb24oaCxpLGos
+ayl7cmV0dXJuIGYodGhpcylbZV0oZyh0aGlzKSxoLGksaixrKX19KGMsdCxzKQpjYXNlIDY6cmV0dXJu
+IGZ1bmN0aW9uKGUsZixnKXtyZXR1cm4gZnVuY3Rpb24oaCxpLGosayxsKXtyZXR1cm4gZih0aGlzKVtl
+XShnKHRoaXMpLGgsaSxqLGssbCl9fShjLHQscykKZGVmYXVsdDpyZXR1cm4gZnVuY3Rpb24oZSxmLGcs
+aCl7cmV0dXJuIGZ1bmN0aW9uKCl7aD1bZyh0aGlzKV0KQXJyYXkucHJvdG90eXBlLnB1c2guYXBwbHko
+aCxhcmd1bWVudHMpCnJldHVybiBlLmFwcGx5KGYodGhpcyksaCl9fShkLHQscyl9fSwKSGY6ZnVuY3Rp
+b24oYSxiKXt2YXIgdCxzLHIscSxwLG8sbj1ILm9OKCksbT0kLlA0CmlmKG09PW51bGwpbT0kLlA0PUgu
+RTIoInJlY2VpdmVyIikKdD1iLiRzdHViTmFtZQpzPWIubGVuZ3RoCnI9YVt0XQpxPWI9PW51bGw/cj09
+bnVsbDpiPT09cgpwPSFxfHxzPj0yOAppZihwKXJldHVybiBILlo0KHMsIXEsdCxiKQppZihzPT09MSl7
+cT0icmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuIitILkVqKG4pKyIuIitILkVqKHQpKyIodGhp
+cy4iK20rIik7IgpwPSQueWoKaWYodHlwZW9mIHAhPT0ibnVtYmVyIilyZXR1cm4gcC5oKCkKJC55aj1w
+KzEKcmV0dXJuIG5ldyBGdW5jdGlvbihxK3ArIn0iKSgpfW89ImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3
+eHl6Ii5zcGxpdCgiIikuc3BsaWNlKDAscy0xKS5qb2luKCIsIikKcT0icmV0dXJuIGZ1bmN0aW9uKCIr
+bysiKXtyZXR1cm4gdGhpcy4iK0guRWoobikrIi4iK0guRWoodCkrIih0aGlzLiIrbSsiLCAiK28rIik7
+IgpwPSQueWoKaWYodHlwZW9mIHAhPT0ibnVtYmVyIilyZXR1cm4gcC5oKCkKJC55aj1wKzEKcmV0dXJu
+IG5ldyBGdW5jdGlvbihxK3ArIn0iKSgpfSwKS3E6ZnVuY3Rpb24oYSxiLGMsZCxlLGYsZyl7cmV0dXJu
+IEguaUEoYSxiLGMsZCwhIWUsISFmLGcpfSwKVG46ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSC5jRSh2LnR5
+cGVVbml2ZXJzZSxILnooYS5hKSxiKX0sClBXOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEguY0Uodi50eXBl
+VW5pdmVyc2UsSC56KGEuYyksYil9LApEVjpmdW5jdGlvbihhKXtyZXR1cm4gYS5hfSwKeVM6ZnVuY3Rp
+b24oYSl7cmV0dXJuIGEuY30sCm9OOmZ1bmN0aW9uKCl7dmFyIHQ9JC5tSgpyZXR1cm4gdD09bnVsbD8k
+Lm1KPUguRTIoInNlbGYiKTp0fSwKRTI6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHE9bmV3IEguclQoInNl
+bGYiLCJ0YXJnZXQiLCJyZWNlaXZlciIsIm5hbWUiKSxwPUouRXAoT2JqZWN0LmdldE93blByb3BlcnR5
+TmFtZXMocSksdS56KQpmb3IodD1wLmxlbmd0aCxzPTA7czx0Oysrcyl7cj1wW3NdCmlmKHFbcl09PT1h
+KXJldHVybiByfXRocm93IEguYihQLnhZKCJGaWVsZCBuYW1lICIrYSsiIG5vdCBmb3VuZC4iKSl9LApv
+VDpmdW5jdGlvbihhKXtpZihhPT1udWxsKUguZk8oImJvb2xlYW4gZXhwcmVzc2lvbiBtdXN0IG5vdCBi
+ZSBudWxsIikKcmV0dXJuIGF9LApmTzpmdW5jdGlvbihhKXt0aHJvdyBILmIobmV3IEgua1koYSkpfSwK
+YWc6ZnVuY3Rpb24oYSl7dGhyb3cgSC5iKG5ldyBQLmMoYSkpfSwKRWY6ZnVuY3Rpb24oYSl7cmV0dXJu
+IG5ldyBILkVxKGEpfSwKWWc6ZnVuY3Rpb24oYSl7cmV0dXJuIHYuZ2V0SXNvbGF0ZVRhZyhhKX0sClZN
+OmZ1bmN0aW9uKGEsYil7YVt2LmFycmF5UnRpXT1iCnJldHVybiBhfSwKb1g6ZnVuY3Rpb24oYSl7aWYo
+YT09bnVsbClyZXR1cm4gbnVsbApyZXR1cm4gYS4kdGl9LApJTTpmdW5jdGlvbihhLGIsYyl7cmV0dXJu
+IEguWTkoYVsiJGEiK0guRWooYyldLEgub1goYikpfSwKWTk6ZnVuY3Rpb24oYSxiKXt2YXIgdAppZihh
+PT1udWxsKXJldHVybiBiCnQ9YS5hcHBseShudWxsLGIpCmlmKHQ9PW51bGwpcmV0dXJuIG51bGwKaWYo
+QXJyYXkuaXNBcnJheSh0KSlyZXR1cm4gdAppZih0eXBlb2YgdD09ImZ1bmN0aW9uIilyZXR1cm4gdC5h
+cHBseShudWxsLGIpCnJldHVybiBifSwKSUc6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBhLmFwcGx5KGIs
+SC5JTShKLmlhKGIpLGIsYykpfSwKaXc6ZnVuY3Rpb24oYSxiLGMpe09iamVjdC5kZWZpbmVQcm9wZXJ0
+eShhLGIse3ZhbHVlOmMsZW51bWVyYWJsZTpmYWxzZSx3cml0YWJsZTp0cnVlLGNvbmZpZ3VyYWJsZTp0
+cnVlfSl9LAp3MzpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG89SC5oKCQuTkYuJDEoYSkpLG49JC5u
+d1tvXQppZihuIT1udWxsKXtPYmplY3QuZGVmaW5lUHJvcGVydHkoYSx2LmRpc3BhdGNoUHJvcGVydHlO
+YW1lLHt2YWx1ZTpuLGVudW1lcmFibGU6ZmFsc2Usd3JpdGFibGU6dHJ1ZSxjb25maWd1cmFibGU6dHJ1
+ZX0pCnJldHVybiBuLml9dD0kLnZ2W29dCmlmKHQhPW51bGwpcmV0dXJuIHQKcz12LmludGVyY2VwdG9y
+c0J5VGFnW29dCmlmKHM9PW51bGwpe3I9SC5rKCQuVFguJDIoYSxvKSkKaWYociE9bnVsbCl7bj0kLm53
+W3JdCmlmKG4hPW51bGwpe09iamVjdC5kZWZpbmVQcm9wZXJ0eShhLHYuZGlzcGF0Y2hQcm9wZXJ0eU5h
+bWUse3ZhbHVlOm4sZW51bWVyYWJsZTpmYWxzZSx3cml0YWJsZTp0cnVlLGNvbmZpZ3VyYWJsZTp0cnVl
+fSkKcmV0dXJuIG4uaX10PSQudnZbcl0KaWYodCE9bnVsbClyZXR1cm4gdApzPXYuaW50ZXJjZXB0b3Jz
+QnlUYWdbcl0Kbz1yfX1pZihzPT1udWxsKXJldHVybiBudWxsCnQ9cy5wcm90b3R5cGUKcT1vWzBdCmlm
+KHE9PT0iISIpe249SC5WYSh0KQokLm53W29dPW4KT2JqZWN0LmRlZmluZVByb3BlcnR5KGEsdi5kaXNw
+YXRjaFByb3BlcnR5TmFtZSx7dmFsdWU6bixlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxlOnRydWUsY29u
+ZmlndXJhYmxlOnRydWV9KQpyZXR1cm4gbi5pfWlmKHE9PT0ifiIpeyQudnZbb109dApyZXR1cm4gdH1p
+ZihxPT09Ii0iKXtwPUguVmEodCkKT2JqZWN0LmRlZmluZVByb3BlcnR5KE9iamVjdC5nZXRQcm90b3R5
+cGVPZihhKSx2LmRpc3BhdGNoUHJvcGVydHlOYW1lLHt2YWx1ZTpwLGVudW1lcmFibGU6ZmFsc2Usd3Jp
+dGFibGU6dHJ1ZSxjb25maWd1cmFibGU6dHJ1ZX0pCnJldHVybiBwLml9aWYocT09PSIrIilyZXR1cm4g
+SC5MYyhhLHQpCmlmKHE9PT0iKiIpdGhyb3cgSC5iKFAuU1kobykpCmlmKHYubGVhZlRhZ3Nbb109PT10
+cnVlKXtwPUguVmEodCkKT2JqZWN0LmRlZmluZVByb3BlcnR5KE9iamVjdC5nZXRQcm90b3R5cGVPZihh
+KSx2LmRpc3BhdGNoUHJvcGVydHlOYW1lLHt2YWx1ZTpwLGVudW1lcmFibGU6ZmFsc2Usd3JpdGFibGU6
+dHJ1ZSxjb25maWd1cmFibGU6dHJ1ZX0pCnJldHVybiBwLml9ZWxzZSByZXR1cm4gSC5MYyhhLHQpfSwK
+TGM6ZnVuY3Rpb24oYSxiKXt2YXIgdD1PYmplY3QuZ2V0UHJvdG90eXBlT2YoYSkKT2JqZWN0LmRlZmlu
+ZVByb3BlcnR5KHQsdi5kaXNwYXRjaFByb3BlcnR5TmFtZSx7dmFsdWU6Si5RdShiLHQsbnVsbCxudWxs
+KSxlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxlOnRydWUsY29uZmlndXJhYmxlOnRydWV9KQpyZXR1cm4g
+Yn0sClZhOmZ1bmN0aW9uKGEpe3JldHVybiBKLlF1KGEsITEsbnVsbCwhIWEuJGlYail9LApWRjpmdW5j
+dGlvbihhLGIsYyl7dmFyIHQ9Yi5wcm90b3R5cGUKaWYodi5sZWFmVGFnc1thXT09PXRydWUpcmV0dXJu
+IEguVmEodCkKZWxzZSByZXR1cm4gSi5RdSh0LGMsbnVsbCxudWxsKX0sClhEOmZ1bmN0aW9uKCl7aWYo
+ITA9PT0kLkJ2KXJldHVybgokLkJ2PSEwCkguWjEoKX0sCloxOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEs
+cCxvLG4sbQokLm53PU9iamVjdC5jcmVhdGUobnVsbCkKJC52dj1PYmplY3QuY3JlYXRlKG51bGwpCkgu
+a08oKQp0PXYuaW50ZXJjZXB0b3JzQnlUYWcKcz1PYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh0KQpp
+Zih0eXBlb2Ygd2luZG93IT0idW5kZWZpbmVkIil7d2luZG93CnI9ZnVuY3Rpb24oKXt9CmZvcihxPTA7
+cTxzLmxlbmd0aDsrK3Epe3A9c1txXQpvPSQueDcuJDEocCkKaWYobyE9bnVsbCl7bj1ILlZGKHAsdFtw
+XSxvKQppZihuIT1udWxsKXtPYmplY3QuZGVmaW5lUHJvcGVydHkobyx2LmRpc3BhdGNoUHJvcGVydHlO
+YW1lLHt2YWx1ZTpuLGVudW1lcmFibGU6ZmFsc2Usd3JpdGFibGU6dHJ1ZSxjb25maWd1cmFibGU6dHJ1
+ZX0pCnIucHJvdG90eXBlPW99fX19Zm9yKHE9MDtxPHMubGVuZ3RoOysrcSl7cD1zW3FdCmlmKC9eW0Et
+WmEtel9dLy50ZXN0KHApKXttPXRbcF0KdFsiISIrcF09bQp0WyJ+IitwXT1tCnRbIi0iK3BdPW0KdFsi
+KyIrcF09bQp0WyIqIitwXT1tfX19LAprTzpmdW5jdGlvbigpe3ZhciB0LHMscixxLHAsbyxuPUMuWXEo
+KQpuPUgudWQoQy5LVSxILnVkKEMuZlEsSC51ZChDLmk3LEgudWQoQy5pNyxILnVkKEMueGksSC51ZChD
+LmRrLEgudWQoQy53YihDLk80KSxuKSkpKSkpKQppZih0eXBlb2YgZGFydE5hdGl2ZURpc3BhdGNoSG9v
+a3NUcmFuc2Zvcm1lciE9InVuZGVmaW5lZCIpe3Q9ZGFydE5hdGl2ZURpc3BhdGNoSG9va3NUcmFuc2Zv
+cm1lcgppZih0eXBlb2YgdD09ImZ1bmN0aW9uIil0PVt0XQppZih0LmNvbnN0cnVjdG9yPT1BcnJheSlm
+b3Iocz0wO3M8dC5sZW5ndGg7KytzKXtyPXRbc10KaWYodHlwZW9mIHI9PSJmdW5jdGlvbiIpbj1yKG4p
+fHxufX1xPW4uZ2V0VGFnCnA9bi5nZXRVbmtub3duVGFnCm89bi5wcm90b3R5cGVGb3JUYWcKJC5ORj1u
+ZXcgSC5kQyhxKQokLlRYPW5ldyBILndOKHApCiQueDc9bmV3IEguVlgobyl9LAp1ZDpmdW5jdGlvbihh
+LGIpe3JldHVybiBhKGIpfHxifSwKdjQ6ZnVuY3Rpb24oYSxiLGMsZCxlLGYpe3ZhciB0PWI/Im0iOiIi
+LHM9Yz8iIjoiaSIscj1kPyJ1IjoiIixxPWU/InMiOiIiLHA9Zj8iZyI6IiIsbz1mdW5jdGlvbihnLGgp
+e3RyeXtyZXR1cm4gbmV3IFJlZ0V4cChnLGgpfWNhdGNoKG4pe3JldHVybiBufX0oYSx0K3MrcitxK3Ap
+CmlmKG8gaW5zdGFuY2VvZiBSZWdFeHApcmV0dXJuIG8KdGhyb3cgSC5iKFAucnIoIklsbGVnYWwgUmVn
+RXhwIHBhdHRlcm4gKCIrU3RyaW5nKG8pKyIpIixhLG51bGwpKX0sCm0yOmZ1bmN0aW9uKGEsYixjKXt2
+YXIgdAppZih0eXBlb2YgYj09InN0cmluZyIpcmV0dXJuIGEuaW5kZXhPZihiLGMpPj0wCmVsc2UgaWYo
+YiBpbnN0YW5jZW9mIEguVlIpe3Q9Qy54Qi5HKGEsYykKcmV0dXJuIGIuYi50ZXN0KHQpfWVsc2V7dD1K
+LkZMKGIsQy54Qi5HKGEsYykpCnJldHVybiF0LmdsMCh0KX19LApBNDpmdW5jdGlvbihhKXtpZihhLmlu
+ZGV4T2YoIiQiLDApPj0wKXJldHVybiBhLnJlcGxhY2UoL1wkL2csIiQkJCQiKQpyZXR1cm4gYX0sCmVB
+OmZ1bmN0aW9uKGEpe2lmKC9bW1xde30oKSorPy5cXF4kfF0vLnRlc3QoYSkpcmV0dXJuIGEucmVwbGFj
+ZSgvW1tcXXt9KCkqKz8uXFxeJHxdL2csIlxcJCYiKQpyZXR1cm4gYX0sCnlzOmZ1bmN0aW9uKGEsYixj
+KXt2YXIgdD1ILm5NKGEsYixjKQpyZXR1cm4gdH0sCm5NOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIs
+cQppZihiPT09IiIpe2lmKGE9PT0iIilyZXR1cm4gYwp0PWEubGVuZ3RoCnM9IiIrYwpmb3Iocj0wO3I8
+dDsrK3Ipcz1zK2Fbcl0rYwpyZXR1cm4gcy5jaGFyQ29kZUF0KDApPT0wP3M6c31xPWEuaW5kZXhPZihi
+LDApCmlmKHE8MClyZXR1cm4gYQppZihhLmxlbmd0aDw1MDB8fGMuaW5kZXhPZigiJCIsMCk+PTApcmV0
+dXJuIGEuc3BsaXQoYikuam9pbihjKQpyZXR1cm4gYS5yZXBsYWNlKG5ldyBSZWdFeHAoSC5lQShiKSwn
+ZycpLEguQTQoYykpfSwKUEQ6ZnVuY3Rpb24gUEQoYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKV1U6
+ZnVuY3Rpb24gV1UoKXt9LApMUDpmdW5jdGlvbiBMUChhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8u
+Yj1iCl8uYz1jCl8uJHRpPWR9LApYUjpmdW5jdGlvbiBYUihhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9
+LApMSTpmdW5jdGlvbiBMSShhLGIsYyxkLGUpe3ZhciBfPXRoaXMKXy5hPWEKXy5jPWIKXy5kPWMKXy5l
+PWQKXy5mPWV9LApDajpmdW5jdGlvbiBDaihhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9
+LApmOTpmdW5jdGlvbiBmOShhLGIsYyxkLGUsZil7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9Ywpf
+LmQ9ZApfLmU9ZQpfLmY9Zn0sClcwOmZ1bmN0aW9uIFcwKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAph
+ejpmdW5jdGlvbiBheihhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LAp2VjpmdW5jdGlv
+biB2VihhKXt0aGlzLmE9YX0sCmJxOmZ1bmN0aW9uIGJxKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApB
+bTpmdW5jdGlvbiBBbShhKXt0aGlzLmE9YX0sClhPOmZ1bmN0aW9uIFhPKGEpe3RoaXMuYT1hCnRoaXMu
+Yj1udWxsfSwKdjpmdW5jdGlvbiB2KCl7fSwKbGM6ZnVuY3Rpb24gbGMoKXt9LAp6eDpmdW5jdGlvbiB6
+eCgpe30sCnJUOmZ1bmN0aW9uIHJUKGEsYixjLGQpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMK
+Xy5kPWR9LApFcTpmdW5jdGlvbiBFcShhKXt0aGlzLmE9YX0sCmtZOmZ1bmN0aW9uIGtZKGEpe3RoaXMu
+YT1hfSwKTjU6ZnVuY3Rpb24gTjUoYSl7dmFyIF89dGhpcwpfLmE9MApfLmY9Xy5lPV8uZD1fLmM9Xy5i
+PW51bGwKXy5yPTAKXy4kdGk9YX0sCmRiOmZ1bmN0aW9uIGRiKGEsYil7dmFyIF89dGhpcwpfLmE9YQpf
+LmI9YgpfLmQ9Xy5jPW51bGx9LAppNTpmdW5jdGlvbiBpNShhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9
+LApONjpmdW5jdGlvbiBONihhLGIsYyl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmQ9Xy5jPW51bGwK
+Xy4kdGk9Y30sCmRDOmZ1bmN0aW9uIGRDKGEpe3RoaXMuYT1hfSwKd046ZnVuY3Rpb24gd04oYSl7dGhp
+cy5hPWF9LApWWDpmdW5jdGlvbiBWWChhKXt0aGlzLmE9YX0sClZSOmZ1bmN0aW9uIFZSKGEsYil7dmFy
+IF89dGhpcwpfLmE9YQpfLmI9YgpfLmQ9Xy5jPW51bGx9LApFSzpmdW5jdGlvbiBFSyhhKXt0aGlzLmI9
+YX0sCktXOmZ1bmN0aW9uIEtXKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sClBiOmZ1
+bmN0aW9uIFBiKGEsYixjKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1udWxsfSwKdFE6
+ZnVuY3Rpb24gdFEoYSxiKXt0aGlzLmE9YQp0aGlzLmM9Yn0sCnVuOmZ1bmN0aW9uIHVuKGEsYixjKXt0
+aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sClNkOmZ1bmN0aW9uIFNkKGEsYixjKXt2YXIgXz10aGlz
+Cl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1udWxsfSwKWEY6ZnVuY3Rpb24oYSl7cmV0dXJuIGF9LApvZDpm
+dW5jdGlvbihhLGIsYyl7aWYoYT4+PjAhPT1hfHxhPj1jKXRocm93IEguYihILkhZKGIsYSkpfSwKck06
+ZnVuY3Rpb24oYSxiLGMpe3ZhciB0CmlmKCEoYT4+PjAhPT1hKSl0PWI+Pj4wIT09Ynx8YT5ifHxiPmMK
+ZWxzZSB0PSEwCmlmKHQpdGhyb3cgSC5iKEguYXUoYSxiLGMpKQpyZXR1cm4gYn0sCkVUOmZ1bmN0aW9u
+IEVUKCl7fSwKYjA6ZnVuY3Rpb24gYjAoKXt9LApEZzpmdW5jdGlvbiBEZygpe30sClBnOmZ1bmN0aW9u
+IFBnKCl7fSwKeGo6ZnVuY3Rpb24geGooKXt9LApkRTpmdW5jdGlvbiBkRSgpe30sClpBOmZ1bmN0aW9u
+IFpBKCl7fSwKZFQ6ZnVuY3Rpb24gZFQoKXt9LApQcTpmdW5jdGlvbiBQcSgpe30sCmVFOmZ1bmN0aW9u
+IGVFKCl7fSwKVjY6ZnVuY3Rpb24gVjYoKXt9LApSRzpmdW5jdGlvbiBSRygpe30sClZQOmZ1bmN0aW9u
+IFZQKCl7fSwKV0I6ZnVuY3Rpb24gV0IoKXt9LApaRzpmdW5jdGlvbiBaRygpe30sCmN6OmZ1bmN0aW9u
+KGEsYil7dmFyIHQ9Yi5jCnJldHVybiB0PT1udWxsP2IuYz1ILkIoYSxiLnosITApOnR9LAp4WjpmdW5j
+dGlvbihhLGIpe3ZhciB0PWIuYwpyZXR1cm4gdD09bnVsbD9iLmM9SC5KKGEsImI4IixbYi56XSk6dH0s
+ClExOmZ1bmN0aW9uKGEpe3ZhciB0PWEueQppZih0PT09Nnx8dD09PTd8fHQ9PT04KXJldHVybiBILlEx
+KGEueikKcmV0dXJuIHQ9PT0xMXx8dD09PTEyfSwKbUQ6ZnVuY3Rpb24oYSl7cmV0dXJuIGEuY3l9LApO
+MDpmdW5jdGlvbihhKXtyZXR1cm4gSC5FKHYudHlwZVVuaXZlcnNlLGEsITEpfSwKUEw6ZnVuY3Rpb24o
+YSxiLGMsYTApe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZixlLGQ9Yi55CnN3aXRjaChk
+KXtjYXNlIDU6Y2FzZSAxOmNhc2UgMjpjYXNlIDM6Y2FzZSA0OnJldHVybiBiCmNhc2UgNjp0PWIuegpz
+PUguUEwoYSx0LGMsYTApCmlmKHM9PT10KXJldHVybiBiCnJldHVybiBILkMoYSxzLCEwKQpjYXNlIDc6
+dD1iLnoKcz1ILlBMKGEsdCxjLGEwKQppZihzPT09dClyZXR1cm4gYgpyZXR1cm4gSC5CKGEscywhMCkK
+Y2FzZSA4OnQ9Yi56CnM9SC5QTChhLHQsYyxhMCkKaWYocz09PXQpcmV0dXJuIGIKcmV0dXJuIEguZihh
+LHMsITApCmNhc2UgOTpyPWIuUQpxPUguYlooYSxyLGMsYTApCmlmKHE9PT1yKXJldHVybiBiCnJldHVy
+biBILkooYSxiLnoscSkKY2FzZSAxMDpwPWIuegpvPUguUEwoYSxwLGMsYTApCm49Yi5RCm09SC5iWihh
+LG4sYyxhMCkKaWYobz09PXAmJm09PT1uKXJldHVybiBiCnJldHVybiBILmEoYSxvLG0pCmNhc2UgMTE6
+bD1iLnoKaz1ILlBMKGEsbCxjLGEwKQpqPWIuUQppPUgucVQoYSxqLGMsYTApCmlmKGs9PT1sJiZpPT09
+ailyZXR1cm4gYgpyZXR1cm4gSC5kKGEsayxpKQpjYXNlIDEyOmg9Yi5RCmEwKz1oLmxlbmd0aApnPUgu
+YlooYSxoLGMsYTApCnA9Yi56Cm89SC5QTChhLHAsYyxhMCkKaWYoZz09PWgmJm89PT1wKXJldHVybiBi
+CnJldHVybiBILkQoYSxvLGcsITApCmNhc2UgMTM6Zj1iLnoKaWYoZjxhMClyZXR1cm4gYgplPWNbZi1h
+MF0KaWYoZT09bnVsbClyZXR1cm4gYgpyZXR1cm4gZQpkZWZhdWx0OnRocm93IEguYihQLmhWKCJBdHRl
+bXB0ZWQgdG8gc3Vic3RpdHV0ZSB1bmV4cGVjdGVkIFJUSSBraW5kICIrZCkpfX0sCmJaOmZ1bmN0aW9u
+KGEsYixjLGQpe3ZhciB0LHMscixxLHA9Yi5sZW5ndGgsbz1bXQpmb3IodD0hMSxzPTA7czxwOysrcyl7
+cj1iW3NdCnE9SC5QTChhLHIsYyxkKQppZihxIT09cil0PSEwCm8ucHVzaChxKX1yZXR1cm4gdD9vOmJ9
+LAp2TzpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxzLHIscSxwLG89Yi5sZW5ndGgsbj1bXQpmb3IodD0h
+MSxzPTA7czxvO3MrPTIpe3I9YltzXQpxPWJbcysxXQpwPUguUEwoYSxxLGMsZCkKaWYocCE9PXEpdD0h
+MApuLnB1c2gocikKbi5wdXNoKHApfXJldHVybiB0P246Yn0sCnFUOmZ1bmN0aW9uKGEsYixjLGQpe3Zh
+ciB0LHM9Yi5hLHI9SC5iWihhLHMsYyxkKSxxPWIuYixwPUguYlooYSxxLGMsZCksbz1iLmMsbj1ILnZP
+KGEsbyxjLGQpCmlmKHI9PT1zJiZwPT09cSYmbj09PW8pcmV0dXJuIGIKdD1uZXcgSC5HKCkKdC5hPXIK
+dC5iPXAKdC5jPW4KcmV0dXJuIHR9LApKUzpmdW5jdGlvbihhKXt2YXIgdD1hLiRTCmlmKHQhPW51bGwp
+e2lmKHR5cGVvZiB0PT0ibnVtYmVyIilyZXR1cm4gSC5CcCh0KQpyZXR1cm4gYS4kUygpfXJldHVybiBu
+dWxsfSwKVWU6ZnVuY3Rpb24oYSxiKXt2YXIgdAppZihILlExKGIpKWlmKGEgaW5zdGFuY2VvZiBILnYp
+e3Q9SC5KUyhhKQppZih0IT1udWxsKXJldHVybiB0fXJldHVybiBILnooYSl9LAp6OmZ1bmN0aW9uKGEp
+e3ZhciB0CmlmKGEgaW5zdGFuY2VvZiBQLk1oKXt0PWEuJHRpCnJldHVybiB0IT1udWxsP3Q6SC5WVShh
+KX1pZihBcnJheS5pc0FycmF5KGEpKXJldHVybiBILnQ2KGEpCnJldHVybiBILlZVKEouaWEoYSkpfSwK
+dDY6ZnVuY3Rpb24oYSl7dmFyIHQ9YVt2LmFycmF5UnRpXSxzPXUuYgppZih0PT1udWxsKXJldHVybiBz
+CmlmKHQuY29uc3RydWN0b3IhPT1zLmNvbnN0cnVjdG9yKXJldHVybiBzCnJldHVybiB0fSwKTGg6ZnVu
+Y3Rpb24oYSl7dmFyIHQ9YS4kdGkKcmV0dXJuIHQhPW51bGw/dDpILlZVKGEpfSwKVlU6ZnVuY3Rpb24o
+YSl7dmFyIHQ9YS5jb25zdHJ1Y3RvcixzPXQuJGNjYWNoZQppZihzIT1udWxsKXJldHVybiBzCnJldHVy
+biBILnI5KGEsdCl9LApyOTpmdW5jdGlvbihhLGIpe3ZhciB0PWEgaW5zdGFuY2VvZiBILnY/YS5fX3By
+b3RvX18uX19wcm90b19fLmNvbnN0cnVjdG9yOmIscz1ILmFpKHYudHlwZVVuaXZlcnNlLHQubmFtZSkK
+Yi4kY2NhY2hlPXMKcmV0dXJuIHN9LApCcDpmdW5jdGlvbihhKXt2YXIgdCxzLHIKSC51UChhKQp0PXYu
+dHlwZXMKcz10W2FdCmlmKHR5cGVvZiBzPT0ic3RyaW5nIil7cj1ILkUodi50eXBlVW5pdmVyc2Uscywh
+MSkKdFthXT1yCnJldHVybiByfXJldHVybiBzfSwKSko6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHE9dGhp
+cwppZihxPT09dS5LKXJldHVybiBILlJFKHEsYSxILmtlKQppZihILkE4KHEpfHxxPT09dS5fKXJldHVy
+biBILlJFKHEsYSxILkl3KQp0PXEueQpzPXQ9PT02P3EuejpxCmlmKHM9PT11LlMpcj1ILm9rCmVsc2Ug
+aWYocz09PXUuZ1J8fHM9PT11LmRpKXI9SC5LSAplbHNlIGlmKHM9PT11Lk4pcj1ILk1NCmVsc2Ugcj1z
+PT09dS55P0gubDpudWxsCmlmKHIhPW51bGwpcmV0dXJuIEguUkUocSxhLHIpCmlmKHMueT09PTkpe3Q9
+cy56CmlmKHMuUS5ldmVyeShILmNjKSl7cS5yPSIkaSIrdApyZXR1cm4gSC5SRShxLGEsSC50NCl9fWVs
+c2UgaWYodD09PTcpcmV0dXJuIEguUkUocSxhLEguQVEpCnJldHVybiBILlJFKHEsYSxILllPKX0sClJF
+OmZ1bmN0aW9uKGEsYixjKXthLmI9YwpyZXR1cm4gYS5iKGIpfSwKQXU6ZnVuY3Rpb24oYSl7dmFyIHQs
+cz10aGlzCkguT3oKaWYoSC5BOChzKXx8cz09PXUuXyl0PUguaG4KZWxzZSBpZihzPT09dS5LKXQ9SC5U
+aQplbHNlIHQ9SC5sNApzLmE9dApyZXR1cm4gcy5hKGEpfSwKUWo6ZnVuY3Rpb24oYSl7dmFyIHQ9YS55
+CnJldHVybiBILkE4KGEpfHxhPT09dS5ffHxhPT09dS5hd3x8dD09PTd8fGE9PT11LlB9LApZTzpmdW5j
+dGlvbihhKXt2YXIgdD10aGlzCmlmKGE9PW51bGwpcmV0dXJuIEguUWoodCkKcmV0dXJuIEguV2Uodi50
+eXBlVW5pdmVyc2UsSC5VZShhLHQpLG51bGwsdCxudWxsKX0sCkFROmZ1bmN0aW9uKGEpe2lmKGE9PW51
+bGwpcmV0dXJuITAKcmV0dXJuIHRoaXMuei5iKGEpfSwKdDQ6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcyxz
+PXQucgppZihhIGluc3RhbmNlb2YgUC5NaClyZXR1cm4hIWFbc10KcmV0dXJuISFKLmlhKGEpW3NdfSwK
+T3o6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcwppZihhPT1udWxsKXJldHVybiBhCmVsc2UgaWYodC5iKGEp
+KXJldHVybiBhCkgubTQoYSx0KX0sCmw0OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMKaWYoYT09bnVsbCly
+ZXR1cm4gYQppZih0LmIoYSkpcmV0dXJuIGEKSC5tNChhLHQpfSwKbTQ6ZnVuY3Rpb24oYSxiKXt0aHJv
+dyBILmIoSC5aYyhILldLKGEsSC5VZShhLGIpLEguZG0oYixudWxsKSkpKX0sCkRoOmZ1bmN0aW9uKGEs
+YixjLGQpe3ZhciB0PW51bGwKaWYoSC5XZSh2LnR5cGVVbml2ZXJzZSxhLHQsYix0KSlyZXR1cm4gYQp0
+aHJvdyBILmIoSC5aYygiVGhlIHR5cGUgYXJndW1lbnQgJyIrSC5FaihILmRtKGEsdCkpKyInIGlzIG5v
+dCBhIHN1YnR5cGUgb2YgdGhlIHR5cGUgdmFyaWFibGUgYm91bmQgJyIrSC5FaihILmRtKGIsdCkpKyIn
+IG9mIHR5cGUgdmFyaWFibGUgJyIrSC5FaihjKSsiJyBpbiAnIitILkVqKGQpKyInLiIpKX0sCldLOmZ1
+bmN0aW9uKGEsYixjKXt2YXIgdD1QLnAoYSkscz1ILmRtKGI9PW51bGw/SC56KGEpOmIsbnVsbCkKcmV0
+dXJuIHQrIjogdHlwZSAnIitILkVqKHMpKyInIGlzIG5vdCBhIHN1YnR5cGUgb2YgdHlwZSAnIitILkVq
+KGMpKyInIn0sClpjOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgSC5pTSgiVHlwZUVycm9yOiAiK2EpfSwK
+cTpmdW5jdGlvbihhLGIpe3JldHVybiBuZXcgSC5pTSgiVHlwZUVycm9yOiAiK0guV0soYSxudWxsLGIp
+KX0sCmtlOmZ1bmN0aW9uKGEpe3JldHVybiBhIT1udWxsfSwKVGk6ZnVuY3Rpb24oYSl7cmV0dXJuIGF9
+LApJdzpmdW5jdGlvbihhKXtyZXR1cm4hMH0sCmhuOmZ1bmN0aW9uKGEpe3JldHVybiBhfSwKbDpmdW5j
+dGlvbihhKXtyZXR1cm4hMD09PWF8fCExPT09YX0sCnA4OmZ1bmN0aW9uKGEpe2lmKCEwPT09YXx8ITE9
+PT1hKXJldHVybiBhCnRocm93IEguYihILnEoYSwiYm9vbCIpKX0sCnk4OmZ1bmN0aW9uKGEpe2lmKCEw
+PT09YXx8ITE9PT1hKXJldHVybiBhCmlmKGE9PW51bGwpcmV0dXJuIGEKdGhyb3cgSC5iKEgucShhLCJi
+b29sIikpfSwKQlI6ZnVuY3Rpb24oYSl7aWYoITA9PT1hfHwhMT09PWEpcmV0dXJuIGEKaWYoYT09bnVs
+bClyZXR1cm4gYQp0aHJvdyBILmIoSC5xKGEsImJvb2w/IikpfSwKRkc6ZnVuY3Rpb24oYSl7aWYodHlw
+ZW9mIGE9PSJudW1iZXIiKXJldHVybiBhCnRocm93IEguYihILnEoYSwiZG91YmxlIikpfSwKR0g6ZnVu
+Y3Rpb24oYSl7aWYodHlwZW9mIGE9PSJudW1iZXIiKXJldHVybiBhCmlmKGE9PW51bGwpcmV0dXJuIGEK
+dGhyb3cgSC5iKEgucShhLCJkb3VibGUiKSl9LApRazpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09Im51
+bWJlciIpcmV0dXJuIGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJvdyBILmIoSC5xKGEsImRvdWJsZT8i
+KSl9LApvazpmdW5jdGlvbihhKXtyZXR1cm4gdHlwZW9mIGE9PSJudW1iZXIiJiZNYXRoLmZsb29yKGEp
+PT09YX0sCklaOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIiYmTWF0aC5mbG9vcihhKT09
+PWEpcmV0dXJuIGEKdGhyb3cgSC5iKEgucShhLCJpbnQiKSl9LAp1UDpmdW5jdGlvbihhKXtpZih0eXBl
+b2YgYT09Im51bWJlciImJk1hdGguZmxvb3IoYSk9PT1hKXJldHVybiBhCmlmKGE9PW51bGwpcmV0dXJu
+IGEKdGhyb3cgSC5iKEgucShhLCJpbnQiKSl9LApVYzpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09Im51
+bWJlciImJk1hdGguZmxvb3IoYSk9PT1hKXJldHVybiBhCmlmKGE9PW51bGwpcmV0dXJuIGEKdGhyb3cg
+SC5iKEgucShhLCJpbnQ/IikpfSwKS0g6ZnVuY3Rpb24oYSl7cmV0dXJuIHR5cGVvZiBhPT0ibnVtYmVy
+In0sCno1OmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIilyZXR1cm4gYQp0aHJvdyBILmIo
+SC5xKGEsIm51bSIpKX0sCm9JOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIilyZXR1cm4g
+YQppZihhPT1udWxsKXJldHVybiBhCnRocm93IEguYihILnEoYSwibnVtIikpfSwKY1U6ZnVuY3Rpb24o
+YSl7aWYodHlwZW9mIGE9PSJudW1iZXIiKXJldHVybiBhCmlmKGE9PW51bGwpcmV0dXJuIGEKdGhyb3cg
+SC5iKEgucShhLCJudW0/IikpfSwKTU06ZnVuY3Rpb24oYSl7cmV0dXJuIHR5cGVvZiBhPT0ic3RyaW5n
+In0sCkJ0OmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ic3RyaW5nIilyZXR1cm4gYQp0aHJvdyBILmIo
+SC5xKGEsIlN0cmluZyIpKX0sCmg6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJzdHJpbmciKXJldHVy
+biBhCmlmKGE9PW51bGwpcmV0dXJuIGEKdGhyb3cgSC5iKEgucShhLCJTdHJpbmciKSl9LAprOmZ1bmN0
+aW9uKGEpe2lmKHR5cGVvZiBhPT0ic3RyaW5nIilyZXR1cm4gYQppZihhPT1udWxsKXJldHVybiBhCnRo
+cm93IEguYihILnEoYSwiU3RyaW5nPyIpKX0sCmlvOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyCmZvcih0
+PSIiLHM9IiIscj0wO3I8YS5sZW5ndGg7KytyLHM9IiwgIil0Kz1DLnhCLmgocyxILmRtKGFbcl0sYikp
+CnJldHVybiB0fSwKYkk6ZnVuY3Rpb24oYTIsYTMsYTQpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGos
+aSxoLGcsZixlLGQsYyxiLGEsYTAsYTE9IiwgIgppZihhNCE9bnVsbCl7dD1hNC5sZW5ndGgKaWYoYTM9
+PW51bGwpe2EzPUguVk0oW10sdS5zKQpzPW51bGx9ZWxzZSBzPWEzLmxlbmd0aApyPWEzLmxlbmd0aApm
+b3IocT10O3E+MDstLXEpQy5ObS5pKGEzLCJUIisocitxKSkKZm9yKHA9dS5fLG89dS5LLG49IjwiLG09
+IiIscT0wO3E8dDsrK3EsbT1hMSl7bis9bQpsPWEzLmxlbmd0aAprPWwtMS1xCmlmKGs8MClyZXR1cm4g
+SC5PSChhMyxrKQpuPUMueEIuaChuLGEzW2tdKQpqPWE0W3FdCmlmKCEoSC5BOChqKXx8aj09PXApKWw9
+IShqPT09bykKZWxzZSBsPSExCmlmKGwpbis9Qy54Qi5oKCIgZXh0ZW5kcyAiLEguZG0oaixhMykpfW4r
+PSI+In1lbHNle249IiIKcz1udWxsfXA9YTIuegppPWEyLlEKaD1pLmEKZz1oLmxlbmd0aApmPWkuYgpl
+PWYubGVuZ3RoCmQ9aS5jCmM9ZC5sZW5ndGgKYj1ILmRtKHAsYTMpCmZvcihhPSIiLGEwPSIiLHE9MDtx
+PGc7KytxLGEwPWExKWErPUMueEIuaChhMCxILmRtKGhbcV0sYTMpKQppZihlPjApe2ErPWEwKyJbIgpm
+b3IoYTA9IiIscT0wO3E8ZTsrK3EsYTA9YTEpYSs9Qy54Qi5oKGEwLEguZG0oZltxXSxhMykpCmErPSJd
+In1pZihjPjApe2ErPWEwKyJ7Igpmb3IoYTA9IiIscT0wO3E8YztxKz0yLGEwPWExKWErPUMueEIuaChh
+MCxILmRtKGRbcSsxXSxhMykpKyIgIitkW3FdCmErPSJ9In1pZihzIT1udWxsKXthMy50b1N0cmluZwph
+My5sZW5ndGg9c31yZXR1cm4gbisiKCIrYSsiKSA9PiAiK0guRWooYil9LApkbTpmdW5jdGlvbihhLGIp
+e3ZhciB0LHMscixxLHAsbyxuLG09YS55CmlmKG09PT01KXJldHVybiJlcmFzZWQiCmlmKG09PT0yKXJl
+dHVybiJkeW5hbWljIgppZihtPT09MylyZXR1cm4idm9pZCIKaWYobT09PTEpcmV0dXJuIk5ldmVyIgpp
+ZihtPT09NClyZXR1cm4iYW55IgppZihtPT09Nil7dD1ILmRtKGEueixiKQpyZXR1cm4gdH1pZihtPT09
+Nyl7cz1hLnoKdD1ILmRtKHMsYikKcj1zLnkKcmV0dXJuIEouYmIocj09PTExfHxyPT09MTI/Qy54Qi5o
+KCIoIix0KSsiKSI6dCwiPyIpfWlmKG09PT04KXJldHVybiJGdXR1cmVPcjwiK0guRWooSC5kbShhLnos
+YikpKyI+IgppZihtPT09OSl7cT1ILm8zKGEueikKcD1hLlEKcmV0dXJuIHAubGVuZ3RoIT09MD9xKygi
+PCIrSC5pbyhwLGIpKyI+Iik6cX1pZihtPT09MTEpcmV0dXJuIEguYkkoYSxiLG51bGwpCmlmKG09PT0x
+MilyZXR1cm4gSC5iSShhLnosYixhLlEpCmlmKG09PT0xMyl7Yi50b1N0cmluZwpvPWEuegpuPWIubGVu
+Z3RoCm89bi0xLW8KaWYobzwwfHxvPj1uKXJldHVybiBILk9IKGIsbykKcmV0dXJuIGJbb119cmV0dXJu
+Ij8ifSwKbzM6ZnVuY3Rpb24oYSl7dmFyIHQscz1ILkpnKGEpCmlmKHMhPW51bGwpcmV0dXJuIHMKdD0i
+bWluaWZpZWQ6IithCnJldHVybiB0fSwKUW86ZnVuY3Rpb24oYSxiKXt2YXIgdD1hLnRSW2JdCmZvcig7
+dHlwZW9mIHQ9PSJzdHJpbmciOyl0PWEudFJbdF0KcmV0dXJuIHR9LAphaTpmdW5jdGlvbihhLGIpe3Zh
+ciB0LHMscixxLHAsbz1hLmVULG49b1tiXQppZihuPT1udWxsKXJldHVybiBILkUoYSxiLCExKQplbHNl
+IGlmKHR5cGVvZiBuPT0ibnVtYmVyIil7dD1uCnM9SC5tKGEsNSwiIyIpCnI9W10KZm9yKHE9MDtxPHQ7
+KytxKXIucHVzaChzKQpwPUguSihhLGIscikKb1tiXT1wCnJldHVybiBwfWVsc2UgcmV0dXJuIG59LAp4
+YjpmdW5jdGlvbihhLGIpe3JldHVybiBILkl4KGEudFIsYil9LApGRjpmdW5jdGlvbihhLGIpe3JldHVy
+biBILkl4KGEuZVQsYil9LApFOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzPWEuZUMscj1zLmdldChiKQpp
+ZihyIT1udWxsKXJldHVybiByCnQ9SC5pKEgubyhhLG51bGwsYixjKSkKcy5zZXQoYix0KQpyZXR1cm4g
+dH0sCmNFOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHI9Yi5jaAppZihyPT1udWxsKXI9Yi5jaD1uZXcg
+TWFwKCkKdD1yLmdldChjKQppZih0IT1udWxsKXJldHVybiB0CnM9SC5pKEgubyhhLGIsYywhMCkpCnIu
+c2V0KGMscykKcmV0dXJuIHN9LAp2NTpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHE9Yi5jeAppZihx
+PT1udWxsKXE9Yi5jeD1uZXcgTWFwKCkKdD1jLmN5CnM9cS5nZXQodCkKaWYocyE9bnVsbClyZXR1cm4g
+cwpyPUguYShhLGIsYy55PT09MTA/Yy5ROltjXSkKcS5zZXQodCxyKQpyZXR1cm4gcn0sCkJEOmZ1bmN0
+aW9uKGEsYil7Yi5hPUguQXUKYi5iPUguSkoKcmV0dXJuIGJ9LAptOmZ1bmN0aW9uKGEsYixjKXt2YXIg
+dCxzLHI9YS5lQy5nZXQoYykKaWYociE9bnVsbClyZXR1cm4gcgp0PW5ldyBILkpjKG51bGwsbnVsbCkK
+dC55PWIKdC5jeT1jCnM9SC5CRChhLHQpCmEuZUMuc2V0KGMscykKcmV0dXJuIHN9LApDOmZ1bmN0aW9u
+KGEsYixjKXt2YXIgdCxzPWIuY3krIioiLHI9YS5lQy5nZXQocykKaWYociE9bnVsbClyZXR1cm4gcgp0
+PUguWjcoYSxiLHMsYykKYS5lQy5zZXQocyx0KQpyZXR1cm4gdH0sClo3OmZ1bmN0aW9uKGEsYixjLGQp
+e3ZhciB0LHMKaWYoZCl7dD1iLnkKaWYoSC5BOChiKXx8Yj09PXUuX3x8Yj09PXUuUHx8dD09PTd8fHQ9
+PT02KXJldHVybiBifXM9bmV3IEguSmMobnVsbCxudWxsKQpzLnk9NgpzLno9YgpzLmN5PWMKcmV0dXJu
+IEguQkQoYSxzKX0sCkI6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHM9Yi5jeSsiPyIscj1hLmVDLmdldChz
+KQppZihyIT1udWxsKXJldHVybiByCnQ9SC5sbChhLGIscyxjKQphLmVDLnNldChzLHQpCnJldHVybiB0
+fSwKbGw6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyLHEKaWYoZCl7dD1iLnkKaWYoIUguQTgoYikp
+aWYoIShiPT09dS5QKSlpZih0IT09NylzPXQ9PT04JiZILmxSKGIueikKZWxzZSBzPSEwCmVsc2Ugcz0h
+MAplbHNlIHM9ITAKaWYocylyZXR1cm4gYgplbHNlIGlmKHQ9PT0xfHxiPT09dS5hdylyZXR1cm4gdS5Q
+CmVsc2UgaWYodD09PTYpe3I9Yi56CmlmKHIueT09PTgmJkgubFIoci56KSlyZXR1cm4gcgplbHNlIHJl
+dHVybiBILmN6KGEsYil9fXE9bmV3IEguSmMobnVsbCxudWxsKQpxLnk9NwpxLno9YgpxLmN5PWMKcmV0
+dXJuIEguQkQoYSxxKX0sCmY6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHM9Yi5jeSsiLyIscj1hLmVDLmdl
+dChzKQppZihyIT1udWxsKXJldHVybiByCnQ9SC5lVihhLGIscyxjKQphLmVDLnNldChzLHQpCnJldHVy
+biB0fSwKZVY6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscwppZihkKXt0PWIueQppZihILkE4KGIpfHxi
+PT09dS5ffHxiPT09dS5LKXJldHVybiBiCmVsc2UgaWYodD09PTEpcmV0dXJuIEguSihhLCJiOCIsW2Jd
+KQplbHNlIGlmKGI9PT11LlApcmV0dXJuIHUuYkd9cz1uZXcgSC5KYyhudWxsLG51bGwpCnMueT04CnMu
+ej1iCnMuY3k9YwpyZXR1cm4gSC5CRChhLHMpfSwKSDpmdW5jdGlvbihhLGIpe3ZhciB0LHMscj0iIiti
+KyJeIixxPWEuZUMuZ2V0KHIpCmlmKHEhPW51bGwpcmV0dXJuIHEKdD1uZXcgSC5KYyhudWxsLG51bGwp
+CnQueT0xMwp0Lno9Ygp0LmN5PXIKcz1ILkJEKGEsdCkKYS5lQy5zZXQocixzKQpyZXR1cm4gc30sClV4
+OmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxPWEubGVuZ3RoCmZvcih0PSIiLHM9IiIscj0wO3I8cTsrK3Is
+cz0iLCIpdCs9cythW3JdLmN5CnJldHVybiB0fSwKUzQ6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxv
+PWEubGVuZ3RoCmZvcih0PSIiLHM9IiIscj0wO3I8bztyKz0yLHM9IiwiKXtxPWFbcl0KcD1hW3IrMV0u
+Y3kKdCs9cytxKyI6IitwfXJldHVybiB0fSwKSjpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHE9Ygpp
+ZihjLmxlbmd0aCE9PTApcSs9IjwiK0guVXgoYykrIj4iCnQ9YS5lQy5nZXQocSkKaWYodCE9bnVsbCly
+ZXR1cm4gdApzPW5ldyBILkpjKG51bGwsbnVsbCkKcy55PTkKcy56PWIKcy5RPWMKaWYoYy5sZW5ndGg+
+MClzLmM9Y1swXQpzLmN5PXEKcj1ILkJEKGEscykKYS5lQy5zZXQocSxyKQpyZXR1cm4gcn0sCmE6ZnVu
+Y3Rpb24oYSxiLGMpe3ZhciB0LHMscixxLHAsbwppZihiLnk9PT0xMCl7dD1iLnoKcz1iLlEuY29uY2F0
+KGMpfWVsc2V7cz1jCnQ9Yn1yPXQuY3krIjsiKygiPCIrSC5VeChzKSsiPiIpCnE9YS5lQy5nZXQocikK
+aWYocSE9bnVsbClyZXR1cm4gcQpwPW5ldyBILkpjKG51bGwsbnVsbCkKcC55PTEwCnAuej10CnAuUT1z
+CnAuY3k9cgpvPUguQkQoYSxwKQphLmVDLnNldChyLG8pCnJldHVybiBvfSwKZDpmdW5jdGlvbihhLGIs
+Yyl7dmFyIHQscyxyLHEscD1iLmN5LG89Yy5hLG49by5sZW5ndGgsbT1jLmIsbD1tLmxlbmd0aCxrPWMu
+YyxqPWsubGVuZ3RoLGk9IigiK0guVXgobykKaWYobD4wKWkrPShuPjA/IiwiOiIiKSsiWyIrSC5VeCht
+KSsiXSIKaWYoaj4wKWkrPShuPjA/IiwiOiIiKSsieyIrSC5TNChrKSsifSIKdD1wKyhpKyIpIikKcz1h
+LmVDLmdldCh0KQppZihzIT1udWxsKXJldHVybiBzCnI9bmV3IEguSmMobnVsbCxudWxsKQpyLnk9MTEK
+ci56PWIKci5RPWMKci5jeT10CnE9SC5CRChhLHIpCmEuZUMuc2V0KHQscSkKcmV0dXJuIHF9LApEOmZ1
+bmN0aW9uKGEsYixjLGQpe3ZhciB0LHM9Yi5jeSsiPCIrSC5VeChjKSsiPiIscj1hLmVDLmdldChzKQpp
+ZihyIT1udWxsKXJldHVybiByCnQ9SC5odyhhLGIsYyxzLGQpCmEuZUMuc2V0KHMsdCkKcmV0dXJuIHR9
+LApodzpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciB0LHMscixxLHAsbyxuLG0KaWYoZSl7dD1jLmxlbmd0
+aApzPW5ldyBBcnJheSh0KQpmb3Iocj0wLHE9MDtxPHQ7KytxKXtwPWNbcV0KaWYocC55PT09MSl7c1tx
+XT1wOysrcn19aWYocj4wKXtvPUguUEwoYSxiLHMsMCkKbj1ILmJaKGEsYyxzLDApCnJldHVybiBILkQo
+YSxvLG4sYyE9PW4pfX1tPW5ldyBILkpjKG51bGwsbnVsbCkKbS55PTEyCm0uej1iCm0uUT1jCm0uY3k9
+ZApyZXR1cm4gSC5CRChhLG0pfSwKbzpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm57dTphLGU6YixyOmMs
+czpbXSxwOjAsbjpkfX0sCmk6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixpPWEu
+cixoPWEucwpmb3IodD1pLmxlbmd0aCxzPTA7czx0Oyl7cj1pLmNoYXJDb2RlQXQocykKaWYocj49NDgm
+JnI8PTU3KXM9SC5BKHMrMSxyLGksaCkKZWxzZSBpZigoKChyfDMyKT4+PjApLTk3JjY1NTM1KTwyNnx8
+cj09PTk1fHxyPT09MzYpcz1ILnQoYSxzLGksaCwhMSkKZWxzZSBpZihyPT09NDYpcz1ILnQoYSxzLGks
+aCwhMCkKZWxzZXsrK3MKc3dpdGNoKHIpe2Nhc2UgNDQ6YnJlYWsKY2FzZSA1ODpicmVhawpjYXNlIDU5
+OmgucHVzaChILksoYS51LGEuZSxoLnBvcCgpKSkKYnJlYWsKY2FzZSA5NDpoLnB1c2goSC5IKGEudSxo
+LnBvcCgpKSkKYnJlYWsKY2FzZSAzNTpoLnB1c2goSC5tKGEudSw1LCIjIikpCmJyZWFrCmNhc2UgNjQ6
+aC5wdXNoKEgubShhLnUsMiwiQCIpKQpicmVhawpjYXNlIDEyNjpoLnB1c2goSC5tKGEudSwzLCJ+Iikp
+CmJyZWFrCmNhc2UgNjA6aC5wdXNoKGEucCkKYS5wPWgubGVuZ3RoCmJyZWFrCmNhc2UgNjI6cT1hLnUK
+cD1oLnNwbGljZShhLnApCkgucihhLnUsYS5lLHApCmEucD1oLnBvcCgpCm89aC5wb3AoKQppZih0eXBl
+b2Ygbz09InN0cmluZyIpaC5wdXNoKEguSihxLG8scCkpCmVsc2V7bj1ILksocSxhLmUsbykKc3dpdGNo
+KG4ueSl7Y2FzZSAxMTpoLnB1c2goSC5EKHEsbixwLGEubikpCmJyZWFrCmRlZmF1bHQ6aC5wdXNoKEgu
+YShxLG4scCkpCmJyZWFrfX1icmVhawpjYXNlIDM4OkguSShhLGgpCmJyZWFrCmNhc2UgNDI6cT1hLnUK
+aC5wdXNoKEguQyhxLEguSyhxLGEuZSxoLnBvcCgpKSxhLm4pKQpicmVhawpjYXNlIDYzOnE9YS51Cmgu
+cHVzaChILkIocSxILksocSxhLmUsaC5wb3AoKSksYS5uKSkKYnJlYWsKY2FzZSA0NzpxPWEudQpoLnB1
+c2goSC5mKHEsSC5LKHEsYS5lLGgucG9wKCkpLGEubikpCmJyZWFrCmNhc2UgNDA6aC5wdXNoKGEucCkK
+YS5wPWgubGVuZ3RoCmJyZWFrCmNhc2UgNDE6cT1hLnUKbT1uZXcgSC5HKCkKbD1xLnNFQQprPXEuc0VB
+Cm89aC5wb3AoKQppZih0eXBlb2Ygbz09Im51bWJlciIpc3dpdGNoKG8pe2Nhc2UtMTpsPWgucG9wKCkK
+YnJlYWsKY2FzZS0yOms9aC5wb3AoKQpicmVhawpkZWZhdWx0OmgucHVzaChvKQpicmVha31lbHNlIGgu
+cHVzaChvKQpwPWguc3BsaWNlKGEucCkKSC5yKGEudSxhLmUscCkKYS5wPWgucG9wKCkKbS5hPXAKbS5i
+PWwKbS5jPWsKaC5wdXNoKEguZChxLEguSyhxLGEuZSxoLnBvcCgpKSxtKSkKYnJlYWsKY2FzZSA5MTpo
+LnB1c2goYS5wKQphLnA9aC5sZW5ndGgKYnJlYWsKY2FzZSA5MzpwPWguc3BsaWNlKGEucCkKSC5yKGEu
+dSxhLmUscCkKYS5wPWgucG9wKCkKaC5wdXNoKHApCmgucHVzaCgtMSkKYnJlYWsKY2FzZSAxMjM6aC5w
+dXNoKGEucCkKYS5wPWgubGVuZ3RoCmJyZWFrCmNhc2UgMTI1OnA9aC5zcGxpY2UoYS5wKQpILnkoYS51
+LGEuZSxwKQphLnA9aC5wb3AoKQpoLnB1c2gocCkKaC5wdXNoKC0yKQpicmVhawpkZWZhdWx0OnRocm93
+IkJhZCBjaGFyYWN0ZXIgIityfX19aj1oLnBvcCgpCnJldHVybiBILksoYS51LGEuZSxqKX0sCkE6ZnVu
+Y3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyPWItNDgKZm9yKHQ9Yy5sZW5ndGg7YTx0OysrYSl7cz1jLmNo
+YXJDb2RlQXQoYSkKaWYoIShzPj00OCYmczw9NTcpKWJyZWFrCnI9cioxMCsocy00OCl9ZC5wdXNoKHIp
+CnJldHVybiBhfSwKdDpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciB0LHMscixxLHAsbyxuPWIrMQpmb3Io
+dD1jLmxlbmd0aDtuPHQ7KytuKXtzPWMuY2hhckNvZGVBdChuKQppZihzPT09NDYpe2lmKGUpYnJlYWsK
+ZT0hMH1lbHNle2lmKCEoKCgoc3wzMik+Pj4wKS05NyY2NTUzNSk8MjZ8fHM9PT05NXx8cz09PTM2KSly
+PXM+PTQ4JiZzPD01NwplbHNlIHI9ITAKaWYoIXIpYnJlYWt9fXE9Yy5zdWJzdHJpbmcoYixuKQppZihl
+KXt0PWEudQpwPWEuZQppZihwLnk9PT0xMClwPXAuegpvPUguUW8odCxwLnopW3FdCmlmKG89PW51bGwp
+SC52aCgnTm8gIicrcSsnIiBpbiAiJytILm1EKHApKyciJykKZC5wdXNoKEguY0UodCxwLG8pKX1lbHNl
+IGQucHVzaChxKQpyZXR1cm4gbn0sCkk6ZnVuY3Rpb24oYSxiKXt2YXIgdD1iLnBvcCgpCmlmKDA9PT10
+KXtiLnB1c2goSC5tKGEudSwxLCIwJiIpKQpyZXR1cm59aWYoMT09PXQpe2IucHVzaChILm0oYS51LDQs
+IjEmIikpCnJldHVybn10aHJvdyBILmIoUC5oVigiVW5leHBlY3RlZCBleHRlbmRlZCBvcGVyYXRpb24g
+IitILkVqKHQpKSl9LApLOmZ1bmN0aW9uKGEsYixjKXtpZih0eXBlb2YgYz09InN0cmluZyIpcmV0dXJu
+IEguSihhLGMsYS5zRUEpCmVsc2UgaWYodHlwZW9mIGM9PSJudW1iZXIiKXJldHVybiBILlRWKGEsYixj
+KQplbHNlIHJldHVybiBjfSwKcjpmdW5jdGlvbihhLGIsYyl7dmFyIHQscz1jLmxlbmd0aApmb3IodD0w
+O3Q8czsrK3QpY1t0XT1ILksoYSxiLGNbdF0pfSwKeTpmdW5jdGlvbihhLGIsYyl7dmFyIHQscz1jLmxl
+bmd0aApmb3IodD0xO3Q8czt0Kz0yKWNbdF09SC5LKGEsYixjW3RdKX0sClRWOmZ1bmN0aW9uKGEsYixj
+KXt2YXIgdCxzLHI9Yi55CmlmKHI9PT0xMCl7aWYoYz09PTApcmV0dXJuIGIuegp0PWIuUQpzPXQubGVu
+Z3RoCmlmKGM8PXMpcmV0dXJuIHRbYy0xXQpjLT1zCmI9Yi56CnI9Yi55fWVsc2UgaWYoYz09PTApcmV0
+dXJuIGIKaWYociE9PTkpdGhyb3cgSC5iKFAuaFYoIkluZGV4ZWQgYmFzZSBtdXN0IGJlIGFuIGludGVy
+ZmFjZSB0eXBlIikpCnQ9Yi5RCmlmKGM8PXQubGVuZ3RoKXJldHVybiB0W2MtMV0KdGhyb3cgSC5iKFAu
+aFYoIkJhZCBpbmRleCAiK2MrIiBmb3IgIitiLncoMCkpKX0sCldlOmZ1bmN0aW9uKGEsYixjLGQsZSl7
+dmFyIHQscyxyLHEscCxvLG4sbSxsLGsKaWYoYj09PWQpcmV0dXJuITAKaWYoSC5BOChkKXx8ZD09PXUu
+XylyZXR1cm4hMAp0PWIueQppZih0PT09NClyZXR1cm4hMAppZihILkE4KGIpKXJldHVybiExCmlmKGI9
+PT11LlApcmV0dXJuITAKcz10PT09MTMKaWYocylpZihILldlKGEsY1tiLnpdLGMsZCxlKSlyZXR1cm4h
+MApyPWQueQppZih0PT09NilyZXR1cm4gSC5XZShhLGIueixjLGQsZSkKaWYocj09PTYpe3E9ZC56CnJl
+dHVybiBILldlKGEsYixjLHEsZSl9aWYodD09PTgpe2lmKCFILldlKGEsYi56LGMsZCxlKSlyZXR1cm4h
+MQpyZXR1cm4gSC5XZShhLEgueFooYSxiKSxjLGQsZSl9aWYodD09PTcpe3E9SC5XZShhLGIueixjLGQs
+ZSkKcmV0dXJuIHF9aWYocj09PTgpe2lmKEguV2UoYSxiLGMsZC56LGUpKXJldHVybiEwCnJldHVybiBI
+LldlKGEsYixjLEgueFooYSxkKSxlKX1pZihyPT09Nyl7cT1ILldlKGEsYixjLGQueixlKQpyZXR1cm4g
+cX1pZihzKXJldHVybiExCnE9dCE9PTExCmlmKCghcXx8dD09PTEyKSYmZD09PXUuWSlyZXR1cm4hMApp
+ZihyPT09MTIpe2lmKGI9PT11LnIpcmV0dXJuITAKaWYodCE9PTEyKXJldHVybiExCnA9Yi5RCm89ZC5R
+Cm49cC5sZW5ndGgKaWYobiE9PW8ubGVuZ3RoKXJldHVybiExCmM9Yz09bnVsbD9wOnAuY29uY2F0KGMp
+CmU9ZT09bnVsbD9vOm8uY29uY2F0KGUpCmZvcihtPTA7bTxuOysrbSl7bD1wW21dCms9b1ttXQppZigh
+SC5XZShhLGwsYyxrLGUpfHwhSC5XZShhLGssZSxsLGMpKXJldHVybiExfXJldHVybiBILmJPKGEsYi56
+LGMsZC56LGUpfWlmKHI9PT0xMSl7aWYoYj09PXUucilyZXR1cm4hMAppZihxKXJldHVybiExCnJldHVy
+biBILmJPKGEsYixjLGQsZSl9aWYodD09PTkpe2lmKHIhPT05KXJldHVybiExCnJldHVybiBILnBHKGEs
+YixjLGQsZSl9cmV0dXJuITF9LApiTzpmdW5jdGlvbihhMCxhMSxhMixhMyxhNCl7dmFyIHQscyxyLHEs
+cCxvLG4sbSxsLGssaixpLGgsZyxmLGUsZCxjLGIsYQppZighSC5XZShhMCxhMS56LGEyLGEzLnosYTQp
+KXJldHVybiExCnQ9YTEuUQpzPWEzLlEKcj10LmEKcT1zLmEKcD1yLmxlbmd0aApvPXEubGVuZ3RoCmlm
+KHA+bylyZXR1cm4hMQpuPW8tcAptPXQuYgpsPXMuYgprPW0ubGVuZ3RoCmo9bC5sZW5ndGgKaWYocCtr
+PG8railyZXR1cm4hMQpmb3IoaT0wO2k8cDsrK2kpe2g9cltpXQppZighSC5XZShhMCxxW2ldLGE0LGgs
+YTIpKXJldHVybiExfWZvcihpPTA7aTxuOysraSl7aD1tW2ldCmlmKCFILldlKGEwLHFbcCtpXSxhNCxo
+LGEyKSlyZXR1cm4hMX1mb3IoaT0wO2k8ajsrK2kpe2g9bVtuK2ldCmlmKCFILldlKGEwLGxbaV0sYTQs
+aCxhMikpcmV0dXJuITF9Zz10LmMKZj1zLmMKZT1nLmxlbmd0aApkPWYubGVuZ3RoCmZvcihpPTAsYz0w
+O2M8ZDtjKz0yKXtiPWZbY10KZG97aWYoaT49ZSlyZXR1cm4hMQphPWdbaV0KaSs9Mn13aGlsZShhPGIp
+CmlmKGI8YSlyZXR1cm4hMQpoPWdbaS0xXQppZighSC5XZShhMCxmW2MrMV0sYTQsaCxhMikpcmV0dXJu
+ITF9cmV0dXJuITB9LApwRzpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciB0LHMscixxLHAsbyxuLG0sbD1i
+Lnosaz1kLnoKaWYobD09PWspe3Q9Yi5RCnM9ZC5RCnI9dC5sZW5ndGgKZm9yKHE9MDtxPHI7KytxKXtw
+PXRbcV0Kbz1zW3FdCmlmKCFILldlKGEscCxjLG8sZSkpcmV0dXJuITF9cmV0dXJuITB9aWYoZD09PXUu
+SylyZXR1cm4hMApuPUguUW8oYSxsKQppZihuPT1udWxsKXJldHVybiExCm09bltrXQppZihtPT1udWxs
+KXJldHVybiExCnI9bS5sZW5ndGgKcz1kLlEKZm9yKHE9MDtxPHI7KytxKWlmKCFILldlKGEsSC5jRShh
+LGIsbVtxXSksYyxzW3FdLGUpKXJldHVybiExCnJldHVybiEwfSwKbFI6ZnVuY3Rpb24oYSl7dmFyIHQs
+cz1hLnkKaWYoIShhPT09dS5QKSlpZighSC5BOChhKSlpZihzIT09NylpZighKHM9PT02JiZILmxSKGEu
+eikpKXQ9cz09PTgmJkgubFIoYS56KQplbHNlIHQ9ITAKZWxzZSB0PSEwCmVsc2UgdD0hMAplbHNlIHQ9
+ITAKcmV0dXJuIHR9LApjYzpmdW5jdGlvbihhKXtyZXR1cm4gSC5BOChhKXx8YT09PXUuX30sCkE4OmZ1
+bmN0aW9uKGEpe3ZhciB0LHM9YS55CmlmKHMhPT0yKWlmKHMhPT0zKWlmKHMhPT00KWlmKHMhPT01KXQ9
+YT09PXUuY0sKZWxzZSB0PSEwCmVsc2UgdD0hMAplbHNlIHQ9ITAKZWxzZSB0PSEwCnJldHVybiB0fSwK
+SXg6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9T2JqZWN0LmtleXMoYikscT1yLmxlbmd0aApmb3IodD0w
+O3Q8cTsrK3Qpe3M9clt0XQphW3NdPWJbc119fSwKSmM6ZnVuY3Rpb24gSmMoYSxiKXt2YXIgXz10aGlz
+Cl8uYT1hCl8uYj1iCl8ueD1fLnI9Xy5jPW51bGwKXy55PTAKXy5jeT1fLmN4PV8uY2g9Xy5RPV8uej1u
+dWxsfSwKRzpmdW5jdGlvbiBHKCl7dGhpcy5jPXRoaXMuYj10aGlzLmE9bnVsbH0sCnU5OmZ1bmN0aW9u
+IHU5KCl7fSwKaU06ZnVuY3Rpb24gaU0oYSl7dGhpcy5hPWF9LApSOTpmdW5jdGlvbihhKXtyZXR1cm4g
+dS53LmIoYSl8fHUuQi5iKGEpfHx1LmR6LmIoYSl8fHUuSS5iKGEpfHx1LkEuYihhKXx8dS5nNC5iKGEp
+fHx1LmcyLmIoYSl9LApKZzpmdW5jdGlvbihhKXtyZXR1cm4gdi5tYW5nbGVkR2xvYmFsTmFtZXNbYV19
+fSxKPXsKUXU6ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJue2k6YSxwOmIsZTpjLHg6ZH19LAprczpmdW5j
+dGlvbihhKXt2YXIgdCxzLHIscSxwPWFbdi5kaXNwYXRjaFByb3BlcnR5TmFtZV0KaWYocD09bnVsbClp
+ZigkLkJ2PT1udWxsKXtILlhEKCkKcD1hW3YuZGlzcGF0Y2hQcm9wZXJ0eU5hbWVdfWlmKHAhPW51bGwp
+e3Q9cC5wCmlmKCExPT09dClyZXR1cm4gcC5pCmlmKCEwPT09dClyZXR1cm4gYQpzPU9iamVjdC5nZXRQ
+cm90b3R5cGVPZihhKQppZih0PT09cylyZXR1cm4gcC5pCmlmKHAuZT09PXMpdGhyb3cgSC5iKFAuU1ko
+IlJldHVybiBpbnRlcmNlcHRvciBmb3IgIitILkVqKHQoYSxwKSkpKX1yPWEuY29uc3RydWN0b3IKcT1y
+PT1udWxsP251bGw6cltKLlJQKCldCmlmKHEhPW51bGwpcmV0dXJuIHEKcT1ILnczKGEpCmlmKHEhPW51
+bGwpcmV0dXJuIHEKaWYodHlwZW9mIGE9PSJmdW5jdGlvbiIpcmV0dXJuIEMuREcKdD1PYmplY3QuZ2V0
+UHJvdG90eXBlT2YoYSkKaWYodD09bnVsbClyZXR1cm4gQy5aUQppZih0PT09T2JqZWN0LnByb3RvdHlw
+ZSlyZXR1cm4gQy5aUQppZih0eXBlb2Ygcj09ImZ1bmN0aW9uIil7T2JqZWN0LmRlZmluZVByb3BlcnR5
+KHIsSi5SUCgpLHt2YWx1ZTpDLnZCLGVudW1lcmFibGU6ZmFsc2Usd3JpdGFibGU6dHJ1ZSxjb25maWd1
+cmFibGU6dHJ1ZX0pCnJldHVybiBDLnZCfXJldHVybiBDLnZCfSwKUlA6ZnVuY3Rpb24oKXt2YXIgdD0k
+LnptCnJldHVybiB0PT1udWxsPyQuem09di5nZXRJc29sYXRlVGFnKCJfJGRhcnRfanMiKTp0fSwKUWk6
+ZnVuY3Rpb24oYSxiKXtpZihhPDB8fGE+NDI5NDk2NzI5NSl0aHJvdyBILmIoUC5URShhLDAsNDI5NDk2
+NzI5NSwibGVuZ3RoIixudWxsKSkKcmV0dXJuIEoucHkobmV3IEFycmF5KGEpLGIpfSwKS2g6ZnVuY3Rp
+b24oYSxiKXtpZihhPDApdGhyb3cgSC5iKFAueFkoIkxlbmd0aCBtdXN0IGJlIGEgbm9uLW5lZ2F0aXZl
+IGludGVnZXI6ICIrYSkpCnJldHVybiBILlZNKG5ldyBBcnJheShhKSxiLkMoImpkPDA+IikpfSwKcHk6
+ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi5FcChILlZNKGEsYi5DKCJqZDwwPiIpKSxiKX0sCkVwOmZ1bmN0
+aW9uKGEsYil7YS5maXhlZCRsZW5ndGg9QXJyYXkKcmV0dXJuIGF9LAp6QzpmdW5jdGlvbihhKXthLmZp
+eGVkJGxlbmd0aD1BcnJheQphLmltbXV0YWJsZSRsaXN0PUFycmF5CnJldHVybiBhfSwKR2E6ZnVuY3Rp
+b24oYSl7aWYoYTwyNTYpc3dpdGNoKGEpe2Nhc2UgOTpjYXNlIDEwOmNhc2UgMTE6Y2FzZSAxMjpjYXNl
+IDEzOmNhc2UgMzI6Y2FzZSAxMzM6Y2FzZSAxNjA6cmV0dXJuITAKZGVmYXVsdDpyZXR1cm4hMX1zd2l0
+Y2goYSl7Y2FzZSA1NzYwOmNhc2UgODE5MjpjYXNlIDgxOTM6Y2FzZSA4MTk0OmNhc2UgODE5NTpjYXNl
+IDgxOTY6Y2FzZSA4MTk3OmNhc2UgODE5ODpjYXNlIDgxOTk6Y2FzZSA4MjAwOmNhc2UgODIwMTpjYXNl
+IDgyMDI6Y2FzZSA4MjMyOmNhc2UgODIzMzpjYXNlIDgyMzk6Y2FzZSA4Mjg3OmNhc2UgMTIyODg6Y2Fz
+ZSA2NTI3OTpyZXR1cm4hMApkZWZhdWx0OnJldHVybiExfX0sCm1tOmZ1bmN0aW9uKGEsYil7dmFyIHQs
+cwpmb3IodD1hLmxlbmd0aDtiPHQ7KXtzPUMueEIuVyhhLGIpCmlmKHMhPT0zMiYmcyE9PTEzJiYhSi5H
+YShzKSlicmVhazsrK2J9cmV0dXJuIGJ9LApjMTpmdW5jdGlvbihhLGIpe3ZhciB0LHMKZm9yKDtiPjA7
+Yj10KXt0PWItMQpzPUMueEIubShhLHQpCmlmKHMhPT0zMiYmcyE9PTEzJiYhSi5HYShzKSlicmVha31y
+ZXR1cm4gYn0sClRKOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIilyZXR1cm4gSi5xSS5w
+cm90b3R5cGUKaWYodHlwZW9mIGE9PSJzdHJpbmciKXJldHVybiBKLkRyLnByb3RvdHlwZQppZihhPT1u
+dWxsKXJldHVybiBhCmlmKGEuY29uc3RydWN0b3I9PUFycmF5KXJldHVybiBKLmpkLnByb3RvdHlwZQpp
+Zih0eXBlb2YgYSE9Im9iamVjdCIpe2lmKHR5cGVvZiBhPT0iZnVuY3Rpb24iKXJldHVybiBKLmM1LnBy
+b3RvdHlwZQpyZXR1cm4gYX1pZihhIGluc3RhbmNlb2YgUC5NaClyZXR1cm4gYQpyZXR1cm4gSi5rcyhh
+KX0sClU2OmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ic3RyaW5nIilyZXR1cm4gSi5Eci5wcm90b3R5
+cGUKaWYoYT09bnVsbClyZXR1cm4gYQppZihhLmNvbnN0cnVjdG9yPT1BcnJheSlyZXR1cm4gSi5qZC5w
+cm90b3R5cGUKaWYodHlwZW9mIGEhPSJvYmplY3QiKXtpZih0eXBlb2YgYT09ImZ1bmN0aW9uIilyZXR1
+cm4gSi5jNS5wcm90b3R5cGUKcmV0dXJuIGF9aWYoYSBpbnN0YW5jZW9mIFAuTWgpcmV0dXJuIGEKcmV0
+dXJuIEoua3MoYSl9LApZRTpmdW5jdGlvbihhKXtpZihhPT1udWxsKXJldHVybiBhCmlmKHR5cGVvZiBh
+IT0ib2JqZWN0Iil7aWYodHlwZW9mIGE9PSJmdW5jdGlvbiIpcmV0dXJuIEouYzUucHJvdG90eXBlCnJl
+dHVybiBhfWlmKGEgaW5zdGFuY2VvZiBQLk1oKXJldHVybiBhCnJldHVybiBKLmtzKGEpfSwKaWE6ZnVu
+Y3Rpb24oYSl7aWYodHlwZW9mIGE9PSJudW1iZXIiKXtpZihNYXRoLmZsb29yKGEpPT1hKXJldHVybiBK
+LnVyLnByb3RvdHlwZQpyZXR1cm4gSi5WQS5wcm90b3R5cGV9aWYodHlwZW9mIGE9PSJzdHJpbmciKXJl
+dHVybiBKLkRyLnByb3RvdHlwZQppZihhPT1udWxsKXJldHVybiBKLndlLnByb3RvdHlwZQppZih0eXBl
+b2YgYT09ImJvb2xlYW4iKXJldHVybiBKLnlFLnByb3RvdHlwZQppZihhLmNvbnN0cnVjdG9yPT1BcnJh
+eSlyZXR1cm4gSi5qZC5wcm90b3R5cGUKaWYodHlwZW9mIGEhPSJvYmplY3QiKXtpZih0eXBlb2YgYT09
+ImZ1bmN0aW9uIilyZXR1cm4gSi5jNS5wcm90b3R5cGUKcmV0dXJuIGF9aWYoYSBpbnN0YW5jZW9mIFAu
+TWgpcmV0dXJuIGEKcmV0dXJuIEoua3MoYSl9LApyWTpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09InN0
+cmluZyIpcmV0dXJuIEouRHIucHJvdG90eXBlCmlmKGE9PW51bGwpcmV0dXJuIGEKaWYoIShhIGluc3Rh
+bmNlb2YgUC5NaCkpcmV0dXJuIEoua2QucHJvdG90eXBlCnJldHVybiBhfSwKdzE6ZnVuY3Rpb24oYSl7
+aWYoYT09bnVsbClyZXR1cm4gYQppZihhLmNvbnN0cnVjdG9yPT1BcnJheSlyZXR1cm4gSi5qZC5wcm90
+b3R5cGUKaWYodHlwZW9mIGEhPSJvYmplY3QiKXtpZih0eXBlb2YgYT09ImZ1bmN0aW9uIilyZXR1cm4g
+Si5jNS5wcm90b3R5cGUKcmV0dXJuIGF9aWYoYSBpbnN0YW5jZW9mIFAuTWgpcmV0dXJuIGEKcmV0dXJu
+IEoua3MoYSl9LApDTTpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm4gSi5ZRShhKS5kdShhLGIsYyxkKX0s
+CkVoOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gSi5ZRShhKS5tSyhhLGIsYyl9LApGTDpmdW5jdGlvbihh
+LGIpe3JldHVybiBKLnJZKGEpLmRkKGEsYil9LApHQTpmdW5jdGlvbihhLGIpe3JldHVybiBKLncxKGEp
+LkUoYSxiKX0sCkdyOmZ1bmN0aW9uKGEpe3JldHVybiBKLllFKGEpLmdtVyhhKX0sCkhtOmZ1bmN0aW9u
+KGEpe3JldHVybiBKLlU2KGEpLmdBKGEpfSwKSVQ6ZnVuY3Rpb24oYSl7cmV0dXJuIEoudzEoYSkuZ2t6
+KGEpfSwKSnk6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi5pYShhKS5lNyhhLGIpfSwKS1Y6ZnVuY3Rpb24o
+YSxiKXtyZXR1cm4gSi5yWShhKS5HKGEsYil9LApMdDpmdW5jdGlvbihhKXtyZXR1cm4gSi5ZRShhKS53
+ZyhhKX0sCk0xOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gSi53MShhKS5FMihhLGIsYyl9LApRejpmdW5j
+dGlvbihhLGIpe3JldHVybiBKLnJZKGEpLlcoYSxiKX0sClJNOmZ1bmN0aW9uKGEsYil7aWYoYT09bnVs
+bClyZXR1cm4gYj09bnVsbAppZih0eXBlb2YgYSE9Im9iamVjdCIpcmV0dXJuIGIhPW51bGwmJmE9PT1i
+CnJldHVybiBKLmlhKGEpLkROKGEsYil9LApUMDpmdW5jdGlvbihhKXtyZXR1cm4gSi5yWShhKS5iUyhh
+KX0sCmE2OmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouclkoYSkubShhLGIpfSwKYlQ6ZnVuY3Rpb24oYSl7
+cmV0dXJuIEouWUUoYSkuRDQoYSl9LApiYjpmdW5jdGlvbihhLGIpe2lmKHR5cGVvZiBhPT0ibnVtYmVy
+IiYmdHlwZW9mIGI9PSJudW1iZXIiKXJldHVybiBhK2IKcmV0dXJuIEouVEooYSkuaChhLGIpfSwKY0g6
+ZnVuY3Rpb24oYSl7cmV0dXJuIEouclkoYSkuaGMoYSl9LApkUjpmdW5jdGlvbihhKXtyZXR1cm4gSi5Z
+RShhKS5nUChhKX0sCmRaOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybiBKLllFKGEpLk9uKGEsYixjLGQp
+fSwKZGc6ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJuIEouclkoYSkuaTcoYSxiLGMsZCl9LApkaDpmdW5j
+dGlvbihhKXtyZXR1cm4gSi5ZRShhKS5GRihhKX0sCmRyOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouWUUo
+YSkuc2E0KGEsYil9LApoZjpmdW5jdGlvbihhKXtyZXR1cm4gSi5pYShhKS5naU8oYSl9LAppZzpmdW5j
+dGlvbihhKXtyZXR1cm4gSi5ZRShhKS5nUWcoYSl9LApqOmZ1bmN0aW9uKGEpe3JldHVybiBKLmlhKGEp
+LncoYSl9LApsNTpmdW5jdGlvbihhLGIpe3JldHVybiBKLllFKGEpLnNoZihhLGIpfSwKbGQ6ZnVuY3Rp
+b24oYSxiLGMpe3JldHVybiBKLnJZKGEpLk5qKGEsYixjKX0sCnA0OmZ1bmN0aW9uKGEsYil7cmV0dXJu
+IEouclkoYSkuVGMoYSxiKX0sCnEwOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gSi5yWShhKS5RaShhLGIs
+Yyl9LApxRjpmdW5jdGlvbihhKXtyZXR1cm4gSi5ZRShhKS5nVmwoYSl9LAp0SDpmdW5jdGlvbihhLGIs
+Yyl7cmV0dXJuIEouWUUoYSkucGsoYSxiLGMpfSwKd2Y6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi5ZRShh
+KS5zUk4oYSxiKX0sCng5OmZ1bmN0aW9uKGEsYil7aWYodHlwZW9mIGI9PT0ibnVtYmVyIilpZihhLmNv
+bnN0cnVjdG9yPT1BcnJheXx8dHlwZW9mIGE9PSJzdHJpbmcifHxILndWKGEsYVt2LmRpc3BhdGNoUHJv
+cGVydHlOYW1lXSkpaWYoYj4+PjA9PT1iJiZiPGEubGVuZ3RoKXJldHVybiBhW2JdCnJldHVybiBKLlU2
+KGEpLnEoYSxiKX0sCnpsOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouVTYoYSkudGcoYSxiKX0sCnZCOmZ1
+bmN0aW9uIHZCKCl7fSwKeUU6ZnVuY3Rpb24geUUoKXt9LAp3ZTpmdW5jdGlvbiB3ZSgpe30sCk1GOmZ1
+bmN0aW9uIE1GKCl7fSwKaUM6ZnVuY3Rpb24gaUMoKXt9LAprZDpmdW5jdGlvbiBrZCgpe30sCmM1OmZ1
+bmN0aW9uIGM1KCl7fSwKamQ6ZnVuY3Rpb24gamQoYSl7dGhpcy4kdGk9YX0sClBvOmZ1bmN0aW9uIFBv
+KGEpe3RoaXMuJHRpPWF9LAptMTpmdW5jdGlvbiBtMShhLGIsYyl7dmFyIF89dGhpcwpfLmE9YQpfLmI9
+YgpfLmM9MApfLmQ9bnVsbApfLiR0aT1jfSwKcUk6ZnVuY3Rpb24gcUkoKXt9LAp1cjpmdW5jdGlvbiB1
+cigpe30sClZBOmZ1bmN0aW9uIFZBKCl7fSwKRHI6ZnVuY3Rpb24gRHIoKXt9fSxQPXsKT2o6ZnVuY3Rp
+b24oKXt2YXIgdCxzLHI9e30KaWYoc2VsZi5zY2hlZHVsZUltbWVkaWF0ZSE9bnVsbClyZXR1cm4gUC5F
+WCgpCmlmKHNlbGYuTXV0YXRpb25PYnNlcnZlciE9bnVsbCYmc2VsZi5kb2N1bWVudCE9bnVsbCl7dD1z
+ZWxmLmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImRpdiIpCnM9c2VsZi5kb2N1bWVudC5jcmVhdGVFbGVt
+ZW50KCJzcGFuIikKci5hPW51bGwKbmV3IHNlbGYuTXV0YXRpb25PYnNlcnZlcihILnRSKG5ldyBQLnRo
+KHIpLDEpKS5vYnNlcnZlKHQse2NoaWxkTGlzdDp0cnVlfSkKcmV0dXJuIG5ldyBQLmhhKHIsdCxzKX1l
+bHNlIGlmKHNlbGYuc2V0SW1tZWRpYXRlIT1udWxsKXJldHVybiBQLnl0KCkKcmV0dXJuIFAucVcoKX0s
+ClpWOmZ1bmN0aW9uKGEpe3NlbGYuc2NoZWR1bGVJbW1lZGlhdGUoSC50UihuZXcgUC5Wcyh1Lk0uYShh
+KSksMCkpfSwKb0E6ZnVuY3Rpb24oYSl7c2VsZi5zZXRJbW1lZGlhdGUoSC50UihuZXcgUC5GdCh1Lk0u
+YShhKSksMCkpfSwKQno6ZnVuY3Rpb24oYSl7dS5NLmEoYSkKUC5RTigwLGEpfSwKUU46ZnVuY3Rpb24o
+YSxiKXt2YXIgdD1uZXcgUC5XMygpCnQuQ1koYSxiKQpyZXR1cm4gdH0sCkZYOmZ1bmN0aW9uKGEpe3Jl
+dHVybiBuZXcgUC5paChuZXcgUC52cygkLlgzLGEuQygidnM8MD4iKSksYS5DKCJpaDwwPiIpKX0sCkRJ
+OmZ1bmN0aW9uKGEsYil7YS4kMigwLG51bGwpCmIuYj0hMApyZXR1cm4gYi5hfSwKalE6ZnVuY3Rpb24o
+YSxiKXtQLkplKGEsYil9LAp5QzpmdW5jdGlvbihhLGIpe2IuYU0oMCxhKX0sCmYzOmZ1bmN0aW9uKGEs
+Yil7Yi53MChILlJ1KGEpLEgudHMoYSkpfSwKSmU6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9bmV3IFAu
+V00oYikscT1uZXcgUC5TWChiKQppZihhIGluc3RhbmNlb2YgUC52cylhLlFkKHIscSx1LnopCmVsc2V7
+dD11LnoKaWYodS5kLmIoYSkpYS5TcShyLHEsdCkKZWxzZXtzPW5ldyBQLnZzKCQuWDMsdS5jKQpzLmE9
+NApzLmM9YQpzLlFkKHIscSx0KX19fSwKbHo6ZnVuY3Rpb24oYSl7dmFyIHQ9ZnVuY3Rpb24oYixjKXty
+ZXR1cm4gZnVuY3Rpb24oZCxlKXt3aGlsZSh0cnVlKXRyeXtiKGQsZSkKYnJlYWt9Y2F0Y2gocyl7ZT1z
+CmQ9Y319fShhLDEpCnJldHVybiAkLlgzLkxqKG5ldyBQLkdzKHQpLHUuUCx1LlMsdS56KX0sCkdROmZ1
+bmN0aW9uKGEpe3JldHVybiBuZXcgUC5GeShhLDEpfSwKVGg6ZnVuY3Rpb24oKXtyZXR1cm4gQy53UX0s
+ClltOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5GeShhLDMpfSwKbDA6ZnVuY3Rpb24oYSxiKXtyZXR1
+cm4gbmV3IFAucTQoYSxiLkMoInE0PDA+IikpfSwKazM6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIKYi5h
+PTEKdHJ5e2EuU3EobmV3IFAucFYoYiksbmV3IFAuVTcoYiksdS5QKX1jYXRjaChyKXt0PUguUnUocikK
+cz1ILnRzKHIpClAucmIobmV3IFAudnIoYix0LHMpKX19LApBOTpmdW5jdGlvbihhLGIpe3ZhciB0LHMs
+cgpmb3IodD11LmM7cz1hLmEscz09PTI7KWE9dC5hKGEuYykKaWYocz49NCl7cj1iLmFoKCkKYi5hPWEu
+YQpiLmM9YS5jClAuSFooYixyKX1lbHNle3I9dS5GLmEoYi5jKQpiLmE9MgpiLmM9YQphLmpRKHIpfX0s
+CkhaOmZ1bmN0aW9uKGEsYTApe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZixlLGQ9bnVs
+bCxjPXt9LGI9Yy5hPWEKZm9yKHQ9dS5uLHM9dS5GLHI9dS5kOyEwOyl7cT17fQpwPWIuYT09PTgKaWYo
+YTA9PW51bGwpe2lmKHApe289dC5hKGIuYykKUC5MMihkLGQsYi5iLG8uYSxvLmIpfXJldHVybn1xLmE9
+YTAKbj1hMC5hCmZvcihiPWEwO24hPW51bGw7Yj1uLG49bSl7Yi5hPW51bGwKUC5IWihjLmEsYikKcS5h
+PW4KbT1uLmF9bD1jLmEKaz1sLmMKcS5iPXAKcS5jPWsKaj0hcAppZihqKXtpPWIuYwppPShpJjEpIT09
+MHx8KGkmMTUpPT09OH1lbHNlIGk9ITAKaWYoaSl7aD1iLmIuYgppZihwKXtpPWwuYj09PWgKaT0hKGl8
+fGkpfWVsc2UgaT0hMQppZihpKXt0LmEoaykKUC5MMihkLGQsbC5iLGsuYSxrLmIpCnJldHVybn1nPSQu
+WDMKaWYoZyE9PWgpJC5YMz1oCmVsc2UgZz1kCmI9Yi5jCmlmKChiJjE1KT09PTgpbmV3IFAuUlQocSxj
+LHApLiQwKCkKZWxzZSBpZihqKXtpZigoYiYxKSE9PTApbmV3IFAucnEocSxrKS4kMCgpfWVsc2UgaWYo
+KGImMikhPT0wKW5ldyBQLlJXKGMscSkuJDAoKQppZihnIT1udWxsKSQuWDM9ZwpiPXEuYwppZihyLmIo
+Yikpe2Y9cS5hLmIKaWYoYi5hPj00KXtlPXMuYShmLmMpCmYuYz1udWxsCmEwPWYuTjgoZSkKZi5hPWIu
+YQpmLmM9Yi5jCmMuYT1iCmNvbnRpbnVlfWVsc2UgUC5BOShiLGYpCnJldHVybn19Zj1xLmEuYgplPXMu
+YShmLmMpCmYuYz1udWxsCmEwPWYuTjgoZSkKYj1xLmIKbD1xLmMKaWYoIWIpe2YuJHRpLmMuYShsKQpm
+LmE9NApmLmM9bH1lbHNle3QuYShsKQpmLmE9OApmLmM9bH1jLmE9ZgpiPWZ9fSwKVkg6ZnVuY3Rpb24o
+YSxiKXt2YXIgdAppZih1LmFnLmIoYSkpcmV0dXJuIGIuTGooYSx1LnosdS5LLHUubCkKdD11LmJJCmlm
+KHQuYihhKSlyZXR1cm4gdC5hKGEpCnRocm93IEguYihQLkwzKGEsIm9uRXJyb3IiLCJFcnJvciBoYW5k
+bGVyIG11c3QgYWNjZXB0IG9uZSBPYmplY3Qgb3Igb25lIE9iamVjdCBhbmQgYSBTdGFja1RyYWNlIGFz
+IGFyZ3VtZW50cywgYW5kIHJldHVybiBhIGEgdmFsaWQgcmVzdWx0IikpfSwKcHU6ZnVuY3Rpb24oKXt2
+YXIgdCxzCmZvcih0PSQuUzY7dCE9bnVsbDt0PSQuUzYpeyQubWc9bnVsbApzPXQuYgokLlM2PXMKaWYo
+cz09bnVsbCkkLms4PW51bGwKdC5hLiQwKCl9fSwKZU46ZnVuY3Rpb24oKXskLlVEPSEwCnRyeXtQLnB1
+KCl9ZmluYWxseXskLm1nPW51bGwKJC5VRD0hMQppZigkLlM2IT1udWxsKSQudXQoKS4kMShQLlY5KCkp
+fX0sCmVXOmZ1bmN0aW9uKGEpe3ZhciB0PW5ldyBQLk9NKGEpLHM9JC5rOAppZihzPT1udWxsKXskLlM2
+PSQuazg9dAppZighJC5VRCkkLnV0KCkuJDEoUC5WOSgpKX1lbHNlICQuazg9cy5iPXR9LApyUjpmdW5j
+dGlvbihhKXt2YXIgdCxzLHIscT0kLlM2CmlmKHE9PW51bGwpe1AuZVcoYSkKJC5tZz0kLms4CnJldHVy
+bn10PW5ldyBQLk9NKGEpCnM9JC5tZwppZihzPT1udWxsKXt0LmI9cQokLlM2PSQubWc9dH1lbHNle3I9
+cy5iCnQuYj1yCiQubWc9cy5iPXQKaWYocj09bnVsbCkkLms4PXR9fSwKcmI6ZnVuY3Rpb24oYSl7dmFy
+IHQ9bnVsbCxzPSQuWDMKaWYoQy5OVT09PXMpe1AuVGsodCx0LEMuTlUsYSkKcmV0dXJufVAuVGsodCx0
+LHMsdS5NLmEocy5HWShhKSkpfSwKUXc6ZnVuY3Rpb24oYSxiKXtQLlVJKGEsInN0cmVhbSIsYi5DKCJx
+aDwwPiIpKQpyZXR1cm4gbmV3IFAueEkoYi5DKCJ4STwwPiIpKX0sClRsOmZ1bmN0aW9uKGEsYil7dmFy
+IHQ9Yj09bnVsbD9QLnYwKGEpOmIKUC5VSShhLCJlcnJvciIsdS5LKQpyZXR1cm4gbmV3IFAuQ3coYSx0
+KX0sCnYwOmZ1bmN0aW9uKGEpe3ZhciB0CmlmKHUuVy5iKGEpKXt0PWEuZ0lJKCkKaWYodCE9bnVsbCly
+ZXR1cm4gdH1yZXR1cm4gQy5wZH0sCkwyOmZ1bmN0aW9uKGEsYixjLGQsZSl7UC5yUihuZXcgUC5wSyhk
+LGUpKX0sClQ4OmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHQscz0kLlgzCmlmKHM9PT1jKXJldHVybiBk
+LiQwKCkKJC5YMz1jCnQ9cwp0cnl7cz1kLiQwKCkKcmV0dXJuIHN9ZmluYWxseXskLlgzPXR9fSwKeXY6
+ZnVuY3Rpb24oYSxiLGMsZCxlLGYsZyl7dmFyIHQscz0kLlgzCmlmKHM9PT1jKXJldHVybiBkLiQxKGUp
+CiQuWDM9Ywp0PXMKdHJ5e3M9ZC4kMShlKQpyZXR1cm4gc31maW5hbGx5eyQuWDM9dH19LApReDpmdW5j
+dGlvbihhLGIsYyxkLGUsZixnLGgsaSl7dmFyIHQscz0kLlgzCmlmKHM9PT1jKXJldHVybiBkLiQyKGUs
+ZikKJC5YMz1jCnQ9cwp0cnl7cz1kLiQyKGUsZikKcmV0dXJuIHN9ZmluYWxseXskLlgzPXR9fSwKVGs6
+ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQKdS5NLmEoZCkKdD1DLk5VIT09YwppZih0KWQ9ISghdHx8ITEp
+P2MuR1koZCk6Yy5SVChkLHUuSCkKUC5lVyhkKX0sCnRoOmZ1bmN0aW9uIHRoKGEpe3RoaXMuYT1hfSwK
+aGE6ZnVuY3Rpb24gaGEoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKVnM6ZnVuY3Rp
+b24gVnMoYSl7dGhpcy5hPWF9LApGdDpmdW5jdGlvbiBGdChhKXt0aGlzLmE9YX0sClczOmZ1bmN0aW9u
+IFczKCl7fSwKeUg6ZnVuY3Rpb24geUgoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCmloOmZ1bmN0aW9u
+IGloKGEsYil7dGhpcy5hPWEKdGhpcy5iPSExCnRoaXMuJHRpPWJ9LApXTTpmdW5jdGlvbiBXTShhKXt0
+aGlzLmE9YX0sClNYOmZ1bmN0aW9uIFNYKGEpe3RoaXMuYT1hfSwKR3M6ZnVuY3Rpb24gR3MoYSl7dGhp
+cy5hPWF9LApGeTpmdW5jdGlvbiBGeShhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKR1Y6ZnVuY3Rpb24g
+R1YoYSxiKXt2YXIgXz10aGlzCl8uYT1hCl8uZD1fLmM9Xy5iPW51bGwKXy4kdGk9Yn0sCnE0OmZ1bmN0
+aW9uIHE0KGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9Yn0sCmI4OmZ1bmN0aW9uIGI4KCl7fSwKUGY6ZnVu
+Y3Rpb24gUGYoKXt9LApaZjpmdW5jdGlvbiBaZihhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApGZTpm
+dW5jdGlvbiBGZShhLGIsYyxkLGUpe3ZhciBfPXRoaXMKXy5hPW51bGwKXy5iPWEKXy5jPWIKXy5kPWMK
+Xy5lPWQKXy4kdGk9ZX0sCnZzOmZ1bmN0aW9uIHZzKGEsYil7dmFyIF89dGhpcwpfLmE9MApfLmI9YQpf
+LmM9bnVsbApfLiR0aT1ifSwKZGE6ZnVuY3Rpb24gZGEoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCm9R
+OmZ1bmN0aW9uIG9RKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApwVjpmdW5jdGlvbiBwVihhKXt0aGlz
+LmE9YX0sClU3OmZ1bmN0aW9uIFU3KGEpe3RoaXMuYT1hfSwKdnI6ZnVuY3Rpb24gdnIoYSxiLGMpe3Ro
+aXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKcnQ6ZnVuY3Rpb24gcnQoYSxiKXt0aGlzLmE9YQp0aGlz
+LmI9Yn0sCktGOmZ1bmN0aW9uIEtGKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApaTDpmdW5jdGlvbiBa
+TChhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApSVDpmdW5jdGlvbiBSVChhLGIsYyl7
+dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApqWjpmdW5jdGlvbiBqWihhKXt0aGlzLmE9YX0sCnJx
+OmZ1bmN0aW9uIHJxKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApSVzpmdW5jdGlvbiBSVyhhLGIpe3Ro
+aXMuYT1hCnRoaXMuYj1ifSwKT006ZnVuY3Rpb24gT00oYSl7dGhpcy5hPWEKdGhpcy5iPW51bGx9LApx
+aDpmdW5jdGlvbiBxaCgpe30sCkI1OmZ1bmN0aW9uIEI1KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAp1
+TzpmdW5jdGlvbiB1TyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKTU86ZnVuY3Rpb24gTU8oKXt9LApr
+VDpmdW5jdGlvbiBrVCgpe30sCnhJOmZ1bmN0aW9uIHhJKGEpe3RoaXMuJHRpPWF9LApDdzpmdW5jdGlv
+biBDdyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKbTA6ZnVuY3Rpb24gbTAoKXt9LApwSzpmdW5jdGlv
+biBwSyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKSmk6ZnVuY3Rpb24gSmkoKXt9LApoajpmdW5jdGlv
+biBoaihhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApWcDpmdW5jdGlvbiBWcChhLGIp
+e3RoaXMuYT1hCnRoaXMuYj1ifSwKT1I6ZnVuY3Rpb24gT1IoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1i
+CnRoaXMuYz1jfSwKRUY6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBiLkMoIkA8MD4iKS5LcShjKS5DKCJG
+bzwxLDI+IikuYShILkI3KGEsbmV3IEguTjUoYi5DKCJAPDA+IikuS3EoYykuQygiTjU8MSwyPiIpKSkp
+fSwKRmw6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IEguTjUoYS5DKCJAPDA+IikuS3EoYikuQygiTjU8
+MSwyPiIpKX0sCkxzOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5iNihhLkMoImI2PDA+IikpfSwKVDI6
+ZnVuY3Rpb24oKXt2YXIgdD1PYmplY3QuY3JlYXRlKG51bGwpCnRbIjxub24taWRlbnRpZmllci1rZXk+
+Il09dApkZWxldGUgdFsiPG5vbi1pZGVudGlmaWVyLWtleT4iXQpyZXR1cm4gdH0sCnJqOmZ1bmN0aW9u
+KGEsYixjKXt2YXIgdD1uZXcgUC5sbShhLGIsYy5DKCJsbTwwPiIpKQp0LmM9YS5lCnJldHVybiB0fSwK
+RVA6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMKaWYoUC5oQihhKSl7aWYoYj09PSIoIiYmYz09PSIpIily
+ZXR1cm4iKC4uLikiCnJldHVybiBiKyIuLi4iK2N9dD1ILlZNKFtdLHUucykKQy5ObS5pKCQueGcsYSkK
+dHJ5e1AuVnIoYSx0KX1maW5hbGx5e2lmKDA+PSQueGcubGVuZ3RoKXJldHVybiBILk9IKCQueGcsLTEp
+CiQueGcucG9wKCl9cz1QLnZnKGIsdS5tLmEodCksIiwgIikrYwpyZXR1cm4gcy5jaGFyQ29kZUF0KDAp
+PT0wP3M6c30sCldFOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzCmlmKFAuaEIoYSkpcmV0dXJuIGIrIi4u
+LiIrYwp0PW5ldyBQLlJuKGIpCkMuTm0uaSgkLnhnLGEpCnRyeXtzPXQKcy5hPVAudmcocy5hLGEsIiwg
+Iil9ZmluYWxseXtpZigwPj0kLnhnLmxlbmd0aClyZXR1cm4gSC5PSCgkLnhnLC0xKQokLnhnLnBvcCgp
+fXQuYSs9YwpzPXQuYQpyZXR1cm4gcy5jaGFyQ29kZUF0KDApPT0wP3M6c30sCmhCOmZ1bmN0aW9uKGEp
+e3ZhciB0LHMKZm9yKHQ9JC54Zy5sZW5ndGgscz0wO3M8dDsrK3MpaWYoYT09PSQueGdbc10pcmV0dXJu
+ITAKcmV0dXJuITF9LApWcjpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAsbyxuLG09YS5na3ooYSks
+bD0wLGs9MAp3aGlsZSghMCl7aWYoIShsPDgwfHxrPDMpKWJyZWFrCmlmKCFtLkYoKSlyZXR1cm4KdD1I
+LkVqKG0uZ2woKSkKQy5ObS5pKGIsdCkKbCs9dC5sZW5ndGgrMjsrK2t9aWYoIW0uRigpKXtpZihrPD01
+KXJldHVybgppZigwPj1iLmxlbmd0aClyZXR1cm4gSC5PSChiLC0xKQpzPWIucG9wKCkKaWYoMD49Yi5s
+ZW5ndGgpcmV0dXJuIEguT0goYiwtMSkKcj1iLnBvcCgpfWVsc2V7cT1tLmdsKCk7KytrCmlmKCFtLkYo
+KSl7aWYoazw9NCl7Qy5ObS5pKGIsSC5FaihxKSkKcmV0dXJufXM9SC5FaihxKQppZigwPj1iLmxlbmd0
+aClyZXR1cm4gSC5PSChiLC0xKQpyPWIucG9wKCkKbCs9cy5sZW5ndGgrMn1lbHNle3A9bS5nbCgpOysr
+awpmb3IoO20uRigpO3E9cCxwPW8pe289bS5nbCgpOysrawppZihrPjEwMCl7d2hpbGUoITApe2lmKCEo
+bD43NSYmaz4zKSlicmVhawppZigwPj1iLmxlbmd0aClyZXR1cm4gSC5PSChiLC0xKQpsLT1iLnBvcCgp
+Lmxlbmd0aCsyOy0ta31DLk5tLmkoYiwiLi4uIikKcmV0dXJufX1yPUguRWoocSkKcz1ILkVqKHApCmwr
+PXMubGVuZ3RoK3IubGVuZ3RoKzR9fWlmKGs+Yi5sZW5ndGgrMil7bCs9NQpuPSIuLi4ifWVsc2Ugbj1u
+dWxsCndoaWxlKCEwKXtpZighKGw+ODAmJmIubGVuZ3RoPjMpKWJyZWFrCmlmKDA+PWIubGVuZ3RoKXJl
+dHVybiBILk9IKGIsLTEpCmwtPWIucG9wKCkubGVuZ3RoKzIKaWYobj09bnVsbCl7bCs9NQpuPSIuLi4i
+fX1pZihuIT1udWxsKUMuTm0uaShiLG4pCkMuTm0uaShiLHIpCkMuTm0uaShiLHMpfSwKdE06ZnVuY3Rp
+b24oYSxiKXt2YXIgdCxzLHI9UC5McyhiKQpmb3IodD1hLmxlbmd0aCxzPTA7czxhLmxlbmd0aDthLmxl
+bmd0aD09PXR8fCgwLEgubGspKGEpLCsrcylyLmkoMCxiLmEoYVtzXSkpCnJldHVybiByfSwKbk86ZnVu
+Y3Rpb24oYSl7dmFyIHQscz17fQppZihQLmhCKGEpKXJldHVybiJ7Li4ufSIKdD1uZXcgUC5SbigiIikK
+dHJ5e0MuTm0uaSgkLnhnLGEpCnQuYSs9InsiCnMuYT0hMAphLksoMCxuZXcgUC5yYShzLHQpKQp0LmEr
+PSJ9In1maW5hbGx5e2lmKDA+PSQueGcubGVuZ3RoKXJldHVybiBILk9IKCQueGcsLTEpCiQueGcucG9w
+KCl9cz10LmEKcmV0dXJuIHMuY2hhckNvZGVBdCgwKT09MD9zOnN9LApiNjpmdW5jdGlvbiBiNihhKXt2
+YXIgXz10aGlzCl8uYT0wCl8uZj1fLmU9Xy5kPV8uYz1fLmI9bnVsbApfLnI9MApfLiR0aT1hfSwKYm46
+ZnVuY3Rpb24gYm4oYSl7dGhpcy5hPWEKdGhpcy5jPXRoaXMuYj1udWxsfSwKbG06ZnVuY3Rpb24gbG0o
+YSxiLGMpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5kPV8uYz1udWxsCl8uJHRpPWN9LAptVzpmdW5j
+dGlvbiBtVygpe30sCkxVOmZ1bmN0aW9uIExVKCl7fSwKbEQ6ZnVuY3Rpb24gbEQoKXt9LAppbDpmdW5j
+dGlvbiBpbCgpe30sCnJhOmZ1bmN0aW9uIHJhKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApZazpmdW5j
+dGlvbiBZaygpe30sCnlROmZ1bmN0aW9uIHlRKGEpe3RoaXMuYT1hfSwKS1A6ZnVuY3Rpb24gS1AoKXt9
+LApQbjpmdW5jdGlvbiBQbigpe30sCkdqOmZ1bmN0aW9uIEdqKGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9
+Yn0sCk1hOmZ1bmN0aW9uIE1hKCl7fSwKVmo6ZnVuY3Rpb24gVmooKXt9LApYdjpmdW5jdGlvbiBYdigp
+e30sCm5ZOmZ1bmN0aW9uIG5ZKCl7fSwKV1k6ZnVuY3Rpb24gV1koKXt9LApSVTpmdW5jdGlvbiBSVSgp
+e30sCkJTOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEKaWYodHlwZW9mIGEhPSJzdHJpbmciKXRocm93
+IEguYihILnRMKGEpKQp0PW51bGwKdHJ5e3Q9SlNPTi5wYXJzZShhKX1jYXRjaChyKXtzPUguUnUocikK
+cT1QLnJyKFN0cmluZyhzKSxudWxsLG51bGwpCnRocm93IEguYihxKX1xPVAuUWUodCkKcmV0dXJuIHF9
+LApRZTpmdW5jdGlvbihhKXt2YXIgdAppZihhPT1udWxsKXJldHVybiBudWxsCmlmKHR5cGVvZiBhIT0i
+b2JqZWN0IilyZXR1cm4gYQppZihPYmplY3QuZ2V0UHJvdG90eXBlT2YoYSkhPT1BcnJheS5wcm90b3R5
+cGUpcmV0dXJuIG5ldyBQLnV3KGEsT2JqZWN0LmNyZWF0ZShudWxsKSkKZm9yKHQ9MDt0PGEubGVuZ3Ro
+OysrdClhW3RdPVAuUWUoYVt0XSkKcmV0dXJuIGF9LApreTpmdW5jdGlvbihhLGIsYyxkKXtpZihiIGlu
+c3RhbmNlb2YgVWludDhBcnJheSlyZXR1cm4gUC5DRyghMSxiLGMsZCkKcmV0dXJuIG51bGx9LApDRzpm
+dW5jdGlvbihhLGIsYyxkKXt2YXIgdCxzLHI9JC5yZigpCmlmKHI9PW51bGwpcmV0dXJuIG51bGwKdD0w
+PT09YwppZih0JiYhMClyZXR1cm4gUC5PUShyLGIpCnM9Yi5sZW5ndGgKZD1QLmpCKGMsZCxzKQppZih0
+JiZkPT09cylyZXR1cm4gUC5PUShyLGIpCnJldHVybiBQLk9RKHIsYi5zdWJhcnJheShjLGQpKX0sCk9R
+OmZ1bmN0aW9uKGEsYil7aWYoUC5BaihiKSlyZXR1cm4gbnVsbApyZXR1cm4gUC5KaChhLGIpfSwKSmg6
+ZnVuY3Rpb24oYSxiKXt2YXIgdCxzCnRyeXt0PWEuZGVjb2RlKGIpCnJldHVybiB0fWNhdGNoKHMpe0gu
+UnUocyl9cmV0dXJuIG51bGx9LApBajpmdW5jdGlvbihhKXt2YXIgdCxzPWEubGVuZ3RoLTIKZm9yKHQ9
+MDt0PHM7Kyt0KWlmKGFbdF09PT0yMzcpaWYoKGFbdCsxXSYyMjQpPT09MTYwKXJldHVybiEwCnJldHVy
+biExfSwKY1A6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscgpmb3IodD1KLlU2KGEpLHM9YjtzPGM7Kytz
+KXtyPXQucShhLHMpCmlmKHR5cGVvZiByIT09Im51bWJlciIpcmV0dXJuIHIuek0oKQppZigociYxMjcp
+IT09cilyZXR1cm4gcy1ifXJldHVybiBjLWJ9LAp4TTpmdW5jdGlvbihhLGIsYyxkLGUsZil7aWYoQy5q
+bi56WShmLDQpIT09MCl0aHJvdyBILmIoUC5ycigiSW52YWxpZCBiYXNlNjQgcGFkZGluZywgcGFkZGVk
+IGxlbmd0aCBtdXN0IGJlIG11bHRpcGxlIG9mIGZvdXIsIGlzICIrZixhLGMpKQppZihkK2UhPT1mKXRo
+cm93IEguYihQLnJyKCJJbnZhbGlkIGJhc2U2NCBwYWRkaW5nLCAnPScgbm90IGF0IHRoZSBlbmQiLGEs
+YikpCmlmKGU+Mil0aHJvdyBILmIoUC5ycigiSW52YWxpZCBiYXNlNjQgcGFkZGluZywgbW9yZSB0aGFu
+IHR3byAnPScgY2hhcmFjdGVycyIsYSxiKSl9LAp1dzpmdW5jdGlvbiB1dyhhLGIpe3RoaXMuYT1hCnRo
+aXMuYj1iCnRoaXMuYz1udWxsfSwKaTg6ZnVuY3Rpb24gaTgoYSl7dGhpcy5hPWF9LApwZzpmdW5jdGlv
+biBwZygpe30sCkNWOmZ1bmN0aW9uIENWKCl7fSwKVTg6ZnVuY3Rpb24gVTgoKXt9LApVazpmdW5jdGlv
+biBVaygpe30sCndJOmZ1bmN0aW9uIHdJKCl7fSwKWmk6ZnVuY3Rpb24gWmkoKXt9LApieTpmdW5jdGlv
+biBieSgpe30sCk14OmZ1bmN0aW9uIE14KGEpe3RoaXMuYT1hfSwKdTU6ZnVuY3Rpb24gdTUoKXt9LApF
+MzpmdW5jdGlvbiBFMygpe30sClJ3OmZ1bmN0aW9uIFJ3KGEpe3RoaXMuYj0wCnRoaXMuYz1hfSwKR1k6
+ZnVuY3Rpb24gR1koYSl7dGhpcy5hPWF9LApiejpmdW5jdGlvbiBieihhLGIpe3ZhciBfPXRoaXMKXy5h
+PWEKXy5iPWIKXy5jPSEwCl8uZj1fLmU9Xy5kPTB9LApRQTpmdW5jdGlvbihhLGIpe3ZhciB0PUguSHAo
+YSxiKQppZih0IT1udWxsKXJldHVybiB0CnRocm93IEguYihQLnJyKGEsbnVsbCxudWxsKSl9LApGOmZ1
+bmN0aW9uKGEpe2lmKGEgaW5zdGFuY2VvZiBILnYpcmV0dXJuIGEudygwKQpyZXR1cm4iSW5zdGFuY2Ug
+b2YgJyIrSC5FaihILk0oYSkpKyInIn0sCk84OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHM9Si5RaShh
+LGQpCmlmKGEhPT0wJiZiIT1udWxsKWZvcih0PTA7dDxzLmxlbmd0aDsrK3Qpc1t0XT1iCnJldHVybiBz
+fSwKQ0g6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHM9SC5WTShbXSxjLkMoImpkPDA+IikpCmZvcih0PUou
+SVQoYSk7dC5GKCk7KUMuTm0uaShzLGMuYSh0LmdsKCkpKQppZihiKXJldHVybiBzCnJldHVybiBKLkVw
+KHMsYyl9LApkSDpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxzPUouS2goYSxkKQpmb3IodD0wO3Q8YTsr
+K3QpQy5ObS5ZKHMsdCxiLiQxKHQpKQpyZXR1cm4gc30sCkFGOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEou
+ekMoUC5DSChhLCExLGIpKX0sCkhNOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzCmlmKEFycmF5LmlzQXJy
+YXkoYSkpe3Q9YQpzPXQubGVuZ3RoCmM9UC5qQihiLGMscykKcmV0dXJuIEguZVQoYj4wfHxjPHM/dC5z
+bGljZShiLGMpOnQpfWlmKHUuYm0uYihhKSlyZXR1cm4gSC5mdyhhLGIsUC5qQihiLGMsYS5sZW5ndGgp
+KQpyZXR1cm4gUC5idyhhLGIsYyl9LApPbzpmdW5jdGlvbihhKXtyZXR1cm4gSC5MdyhhKX0sCmJ3OmZ1
+bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscSxwPW51bGwKaWYoYjwwKXRocm93IEguYihQLlRFKGIsMCxK
+LkhtKGEpLHAscCkpCnQ9Yz09bnVsbAppZighdCYmYzxiKXRocm93IEguYihQLlRFKGMsYixKLkhtKGEp
+LHAscCkpCnM9Si5JVChhKQpmb3Iocj0wO3I8YjsrK3IpaWYoIXMuRigpKXRocm93IEguYihQLlRFKGIs
+MCxyLHAscCkpCnE9W10KaWYodClmb3IoO3MuRigpOylxLnB1c2gocy5nbCgpKQplbHNlIGZvcihyPWI7
+cjxjOysrcil7aWYoIXMuRigpKXRocm93IEguYihQLlRFKGMsYixyLHAscCkpCnEucHVzaChzLmdsKCkp
+fXJldHVybiBILmVUKHEpfSwKbnU6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBILlZSKGEsSC52NChhLCEx
+LCEwLCExLCExLCExKSl9LAp2ZzpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9Si5JVChiKQppZighdC5GKCkp
+cmV0dXJuIGEKaWYoYy5sZW5ndGg9PT0wKXtkbyBhKz1ILkVqKHQuZ2woKSkKd2hpbGUodC5GKCkpfWVs
+c2V7YSs9SC5Faih0LmdsKCkpCmZvcig7dC5GKCk7KWE9YStjK0guRWoodC5nbCgpKX1yZXR1cm4gYX0s
+CmxyOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybiBuZXcgUC5tcChhLGIsYyxkKX0sCnVvOmZ1bmN0aW9u
+KCl7dmFyIHQ9SC5NMCgpCmlmKHQhPW51bGwpcmV0dXJuIFAuaEsodCkKdGhyb3cgSC5iKFAuTDQoIidV
+cmkuYmFzZScgaXMgbm90IHN1cHBvcnRlZCIpKX0sCmVQOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMs
+cixxLHAsbyxuPSIwMTIzNDU2Nzg5QUJDREVGIgppZihjPT09Qy54TSl7dD0kLno0KCkuYgppZih0eXBl
+b2YgYiE9InN0cmluZyIpSC52aChILnRMKGIpKQp0PXQudGVzdChiKX1lbHNlIHQ9ITEKaWYodClyZXR1
+cm4gYgpILkxoKGMpLkMoIlVrLlMiKS5hKGIpCnM9Yy5nWkUoKS5XSihiKQpmb3IodD1zLmxlbmd0aCxy
+PTAscT0iIjtyPHQ7KytyKXtwPXNbcl0KaWYocDwxMjgpe289cD4+PjQKaWYobz49OClyZXR1cm4gSC5P
+SChhLG8pCm89KGFbb10mMTw8KHAmMTUpKSE9PTB9ZWxzZSBvPSExCmlmKG8pcSs9SC5MdyhwKQplbHNl
+IHE9ZCYmcD09PTMyP3ErIisiOnErIiUiK25bcD4+PjQmMTVdK25bcCYxNV19cmV0dXJuIHEuY2hhckNv
+ZGVBdCgwKT09MD9xOnF9LApHcTpmdW5jdGlvbihhKXt2YXIgdD1NYXRoLmFicyhhKSxzPWE8MD8iLSI6
+IiIKaWYodD49MTAwMClyZXR1cm4iIithCmlmKHQ+PTEwMClyZXR1cm4gcysiMCIrdAppZih0Pj0xMCly
+ZXR1cm4gcysiMDAiK3QKcmV0dXJuIHMrIjAwMCIrdH0sClZ4OmZ1bmN0aW9uKGEpe2lmKGE+PTEwMCly
+ZXR1cm4iIithCmlmKGE+PTEwKXJldHVybiIwIithCnJldHVybiIwMCIrYX0sCmgwOmZ1bmN0aW9uKGEp
+e2lmKGE+PTEwKXJldHVybiIiK2EKcmV0dXJuIjAiK2F9LApwOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBh
+PT0ibnVtYmVyInx8SC5sKGEpfHxudWxsPT1hKXJldHVybiBKLmooYSkKaWYodHlwZW9mIGE9PSJzdHJp
+bmciKXJldHVybiBKU09OLnN0cmluZ2lmeShhKQpyZXR1cm4gUC5GKGEpfSwKaFY6ZnVuY3Rpb24oYSl7
+cmV0dXJuIG5ldyBQLkM2KGEpfSwKeFk6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLnUoITEsbnVsbCxu
+dWxsLGEpfSwKTDM6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBuZXcgUC51KCEwLGEsYixjKX0sClVJOmZ1
+bmN0aW9uKGEsYixjKXtpZihhPT1udWxsKXRocm93IEguYihuZXcgUC51KCExLG51bGwsYiwiTXVzdCBu
+b3QgYmUgbnVsbCIpKQpyZXR1cm4gYX0sCk83OmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBQLmJKKG51
+bGwsbnVsbCwhMCxhLGIsIlZhbHVlIG5vdCBpbiByYW5nZSIpfSwKVEU6ZnVuY3Rpb24oYSxiLGMsZCxl
+KXtyZXR1cm4gbmV3IFAuYkooYixjLCEwLGEsZCwiSW52YWxpZCB2YWx1ZSIpfSwKd0E6ZnVuY3Rpb24o
+YSxiLGMsZCl7aWYoYTxifHxhPmMpdGhyb3cgSC5iKFAuVEUoYSxiLGMsZCxudWxsKSkKcmV0dXJuIGF9
+LApqQjpmdW5jdGlvbihhLGIsYyl7aWYoMD5hfHxhPmMpdGhyb3cgSC5iKFAuVEUoYSwwLGMsInN0YXJ0
+IixudWxsKSkKaWYoYiE9bnVsbCl7aWYoYT5ifHxiPmMpdGhyb3cgSC5iKFAuVEUoYixhLGMsImVuZCIs
+bnVsbCkpCnJldHVybiBifXJldHVybiBjfSwKazE6ZnVuY3Rpb24oYSxiKXtpZihhPDApdGhyb3cgSC5i
+KFAuVEUoYSwwLG51bGwsYixudWxsKSkKcmV0dXJuIGF9LApDZjpmdW5jdGlvbihhLGIsYyxkLGUpe3Zh
+ciB0PUgudVAoZT09bnVsbD9KLkhtKGIpOmUpCnJldHVybiBuZXcgUC5lWSh0LCEwLGEsYywiSW5kZXgg
+b3V0IG9mIHJhbmdlIil9LApMNDpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAudWIoYSl9LApTWTpmdW5j
+dGlvbihhKXtyZXR1cm4gbmV3IFAuZHMoYSl9LApQVjpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAubGoo
+YSl9LAphNDpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuVVYoYSl9LApycjpmdW5jdGlvbihhLGIsYyl7
+cmV0dXJuIG5ldyBQLmFFKGEsYixjKX0sCmhLOmZ1bmN0aW9uKGE0KXt2YXIgdCxzLHIscSxwLG8sbixt
+LGwsayxqLGksaCxnLGYsZSxkLGMsYixhLGEwLGExLGEyPW51bGwsYTM9YTQubGVuZ3RoCmlmKGEzPj01
+KXt0PSgoSi5ReihhNCw0KV41OCkqM3xDLnhCLlcoYTQsMCleMTAwfEMueEIuVyhhNCwxKV45N3xDLnhC
+LlcoYTQsMileMTE2fEMueEIuVyhhNCwzKV45Nyk+Pj4wCmlmKHQ9PT0wKXJldHVybiBQLktEKGEzPGEz
+P0MueEIuTmooYTQsMCxhMyk6YTQsNSxhMikuZ2xSKCkKZWxzZSBpZih0PT09MzIpcmV0dXJuIFAuS0Qo
+Qy54Qi5OaihhNCw1LGEzKSwwLGEyKS5nbFIoKX1zPVAuTzgoOCwwLCExLHUuUykKQy5ObS5ZKHMsMCww
+KQpDLk5tLlkocywxLC0xKQpDLk5tLlkocywyLC0xKQpDLk5tLlkocyw3LC0xKQpDLk5tLlkocywzLDAp
+CkMuTm0uWShzLDQsMCkKQy5ObS5ZKHMsNSxhMykKQy5ObS5ZKHMsNixhMykKaWYoUC5VQihhNCwwLGEz
+LDAscyk+PTE0KUMuTm0uWShzLDcsYTMpCmlmKDE+PXMubGVuZ3RoKXJldHVybiBILk9IKHMsMSkKcj1z
+WzFdCmlmKHI+PTApaWYoUC5VQihhNCwwLHIsMjAscyk9PT0yMCl7aWYoNz49cy5sZW5ndGgpcmV0dXJu
+IEguT0gocyw3KQpzWzddPXJ9cT1zLmxlbmd0aAppZigyPj1xKXJldHVybiBILk9IKHMsMikKcD1zWzJd
+KzEKaWYoMz49cSlyZXR1cm4gSC5PSChzLDMpCm89c1szXQppZig0Pj1xKXJldHVybiBILk9IKHMsNCkK
+bj1zWzRdCmlmKDU+PXEpcmV0dXJuIEguT0gocyw1KQptPXNbNV0KaWYoNj49cSlyZXR1cm4gSC5PSChz
+LDYpCmw9c1s2XQppZihsPG0pbT1sCmlmKG48cCluPW0KZWxzZSBpZihuPD1yKW49cisxCmlmKG88cClv
+PW4KaWYoNz49cSlyZXR1cm4gSC5PSChzLDcpCms9c1s3XTwwCmlmKGspaWYocD5yKzMpe2o9YTIKaz0h
+MX1lbHNle3E9bz4wCmlmKHEmJm8rMT09PW4pe2o9YTIKaz0hMX1lbHNle2lmKCEobTxhMyYmbT09PW4r
+MiYmSi5xMChhNCwiLi4iLG4pKSlpPW0+bisyJiZKLnEwKGE0LCIvLi4iLG0tMykKZWxzZSBpPSEwCmlm
+KGkpe2o9YTIKaz0hMX1lbHNle2lmKHI9PT00KWlmKEoucTAoYTQsImZpbGUiLDApKXtpZihwPD0wKXtp
+ZighQy54Qi5RaShhNCwiLyIsbikpe2g9ImZpbGU6Ly8vIgp0PTN9ZWxzZXtoPSJmaWxlOi8vIgp0PTJ9
+YTQ9aCtDLnhCLk5qKGE0LG4sYTMpCnItPTAKcT10LTAKbSs9cQpsKz1xCmEzPWE0Lmxlbmd0aApwPTcK
+bz03Cm49N31lbHNlIGlmKG49PT1tKXsrK2wKZz1tKzEKYTQ9Qy54Qi5pNyhhNCxuLG0sIi8iKTsrK2Ez
+Cm09Z31qPSJmaWxlIn1lbHNlIGlmKEMueEIuUWkoYTQsImh0dHAiLDApKXtpZihxJiZvKzM9PT1uJiZD
+LnhCLlFpKGE0LCI4MCIsbysxKSl7bC09MwpmPW4tMwptLT0zCmE0PUMueEIuaTcoYTQsbyxuLCIiKQph
+My09MwpuPWZ9aj0iaHR0cCJ9ZWxzZSBqPWEyCmVsc2UgaWYocj09PTUmJkoucTAoYTQsImh0dHBzIiww
+KSl7aWYocSYmbys0PT09biYmSi5xMChhNCwiNDQzIixvKzEpKXtsLT00CmY9bi00Cm0tPTQKYTQ9Si5k
+ZyhhNCxvLG4sIiIpCmEzLT0zCm49Zn1qPSJodHRwcyJ9ZWxzZSBqPWEyCms9ITB9fX1lbHNlIGo9YTIK
+aWYoayl7cT1hNC5sZW5ndGgKaWYoYTM8cSl7YTQ9Si5sZChhNCwwLGEzKQpyLT0wCnAtPTAKby09MApu
+LT0wCm0tPTAKbC09MH1yZXR1cm4gbmV3IFAuVWYoYTQscixwLG8sbixtLGwsail9aWYoaj09bnVsbClp
+ZihyPjApaj1QLlBpKGE0LDAscikKZWxzZXtpZihyPT09MClQLlIzKGE0LDAsIkludmFsaWQgZW1wdHkg
+c2NoZW1lIikKaj0iIn1pZihwPjApe2U9ciszCmQ9ZTxwP1AuelIoYTQsZSxwLTEpOiIiCmM9UC5PZShh
+NCxwLG8sITEpCnE9bysxCmlmKHE8bil7Yj1ILkhwKEoubGQoYTQscSxuKSxhMikKYT1QLndCKGI9PW51
+bGw/SC52aChQLnJyKCJJbnZhbGlkIHBvcnQiLGE0LHEpKTpiLGopfWVsc2UgYT1hMn1lbHNle2E9YTIK
+Yz1hCmQ9IiJ9YTA9UC5rYShhNCxuLG0sYTIsaixjIT1udWxsKQphMT1tPGw/UC5sZShhNCxtKzEsbCxh
+Mik6YTIKcmV0dXJuIG5ldyBQLkRuKGosZCxjLGEsYTAsYTEsbDxhMz9QLnRHKGE0LGwrMSxhMyk6YTIp
+fSwKTXQ6ZnVuY3Rpb24oYSl7SC5oKGEpCnJldHVybiBQLmt1KGEsMCxhLmxlbmd0aCxDLnhNLCExKX0s
+CldYOmZ1bmN0aW9uKGEpe3ZhciB0PXUuTgpyZXR1cm4gQy5ObS5OMChILlZNKGEuc3BsaXQoIiYiKSx1
+LnMpLFAuRmwodCx0KSxuZXcgUC5uMShDLnhNKSx1LmYpfSwKSGg6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0
+LHMscixxLHAsbyxuLG09IklQdjQgYWRkcmVzcyBzaG91bGQgY29udGFpbiBleGFjdGx5IDQgcGFydHMi
+LGw9ImVhY2ggcGFydCBtdXN0IGJlIGluIHRoZSByYW5nZSAwLi4yNTUiLGs9bmV3IFAuY1MoYSksaj1u
+ZXcgVWludDhBcnJheSg0KQpmb3IodD1qLmxlbmd0aCxzPWIscj1zLHE9MDtzPGM7KytzKXtwPUMueEIu
+bShhLHMpCmlmKHAhPT00Nil7aWYoKHBeNDgpPjkpay4kMigiaW52YWxpZCBjaGFyYWN0ZXIiLHMpfWVs
+c2V7aWYocT09PTMpay4kMihtLHMpCm89UC5RQShDLnhCLk5qKGEscixzKSxudWxsKQppZih0eXBlb2Yg
+byE9PSJudW1iZXIiKXJldHVybiBvLm9zKCkKaWYobz4yNTUpay4kMihsLHIpCm49cSsxCmlmKHE+PXQp
+cmV0dXJuIEguT0goaixxKQpqW3FdPW8Kcj1zKzEKcT1ufX1pZihxIT09MylrLiQyKG0sYykKbz1QLlFB
+KEMueEIuTmooYSxyLGMpLG51bGwpCmlmKHR5cGVvZiBvIT09Im51bWJlciIpcmV0dXJuIG8ub3MoKQpp
+ZihvPjI1NSlrLiQyKGwscikKaWYocT49dClyZXR1cm4gSC5PSChqLHEpCmpbcV09bwpyZXR1cm4gan0s
+CmVnOmZ1bmN0aW9uKGEsYixhMCl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixpLGgsZyxmLGUsZD1u
+ZXcgUC5WQyhhKSxjPW5ldyBQLkpUKGQsYSkKaWYoYS5sZW5ndGg8MilkLiQxKCJhZGRyZXNzIGlzIHRv
+byBzaG9ydCIpCnQ9SC5WTShbXSx1LnQpCmZvcihzPWIscj1zLHE9ITEscD0hMTtzPGEwOysrcyl7bz1D
+LnhCLm0oYSxzKQppZihvPT09NTgpe2lmKHM9PT1iKXsrK3MKaWYoQy54Qi5tKGEscykhPT01OClkLiQy
+KCJpbnZhbGlkIHN0YXJ0IGNvbG9uLiIscykKcj1zfWlmKHM9PT1yKXtpZihxKWQuJDIoIm9ubHkgb25l
+IHdpbGRjYXJkIGA6OmAgaXMgYWxsb3dlZCIscykKQy5ObS5pKHQsLTEpCnE9ITB9ZWxzZSBDLk5tLmko
+dCxjLiQyKHIscykpCnI9cysxfWVsc2UgaWYobz09PTQ2KXA9ITB9aWYodC5sZW5ndGg9PT0wKWQuJDEo
+InRvbyBmZXcgcGFydHMiKQpuPXI9PT1hMAptPUMuTm0uZ3JaKHQpCmlmKG4mJm0hPT0tMSlkLiQyKCJl
+eHBlY3RlZCBhIHBhcnQgYWZ0ZXIgbGFzdCBgOmAiLGEwKQppZighbilpZighcClDLk5tLmkodCxjLiQy
+KHIsYTApKQplbHNle2w9UC5IaChhLHIsYTApCkMuTm0uaSh0LChsWzBdPDw4fGxbMV0pPj4+MCkKQy5O
+bS5pKHQsKGxbMl08PDh8bFszXSk+Pj4wKX1pZihxKXtpZih0Lmxlbmd0aD43KWQuJDEoImFuIGFkZHJl
+c3Mgd2l0aCBhIHdpbGRjYXJkIG11c3QgaGF2ZSBsZXNzIHRoYW4gNyBwYXJ0cyIpfWVsc2UgaWYodC5s
+ZW5ndGghPT04KWQuJDEoImFuIGFkZHJlc3Mgd2l0aG91dCBhIHdpbGRjYXJkIG11c3QgY29udGFpbiBl
+eGFjdGx5IDggcGFydHMiKQprPW5ldyBVaW50OEFycmF5KDE2KQpmb3IobT10Lmxlbmd0aCxqPWsubGVu
+Z3RoLGk9OS1tLHM9MCxoPTA7czxtOysrcyl7Zz10W3NdCmlmKGc9PT0tMSlmb3IoZj0wO2Y8aTsrK2Yp
+e2lmKGg8MHx8aD49ailyZXR1cm4gSC5PSChrLGgpCmtbaF09MAplPWgrMQppZihlPj1qKXJldHVybiBI
+Lk9IKGssZSkKa1tlXT0wCmgrPTJ9ZWxzZXtlPUMuam4ud0coZyw4KQppZihoPDB8fGg+PWopcmV0dXJu
+IEguT0goayxoKQprW2hdPWUKZT1oKzEKaWYoZT49ailyZXR1cm4gSC5PSChrLGUpCmtbZV09ZyYyNTUK
+aCs9Mn19cmV0dXJuIGt9LApLTDpmdW5jdGlvbihhLGIsYyxkLGUsZixnKXt2YXIgdCxzLHIscSxwLG8K
+Zj1mPT1udWxsPyIiOlAuUGkoZiwwLGYubGVuZ3RoKQpnPVAuelIoZywwLGc9PW51bGw/MDpnLmxlbmd0
+aCkKYT1QLk9lKGEsMCxhPT1udWxsPzA6YS5sZW5ndGgsITEpCnQ9UC5sZShudWxsLDAsMCxlKQpzPVAu
+dEcobnVsbCwwLDApCmQ9UC53QihkLGYpCnI9Zj09PSJmaWxlIgppZihhPT1udWxsKXE9Zy5sZW5ndGgh
+PT0wfHxkIT1udWxsfHxyCmVsc2UgcT0hMQppZihxKWE9IiIKcT1hPT1udWxsCnA9IXEKYj1QLmthKGIs
+MCxiPT1udWxsPzA6Yi5sZW5ndGgsYyxmLHApCm89Zi5sZW5ndGg9PT0wCmlmKG8mJnEmJiFDLnhCLm4o
+YiwiLyIpKWI9UC53RihiLCFvfHxwKQplbHNlIGI9UC54ZShiKQpyZXR1cm4gbmV3IFAuRG4oZixnLHEm
+JkMueEIubihiLCIvLyIpPyIiOmEsZCxiLHQscyl9LAp3SzpmdW5jdGlvbihhKXtpZihhPT09Imh0dHAi
+KXJldHVybiA4MAppZihhPT09Imh0dHBzIilyZXR1cm4gNDQzCnJldHVybiAwfSwKUjM6ZnVuY3Rpb24o
+YSxiLGMpe3Rocm93IEguYihQLnJyKGMsYSxiKSl9LApYZDpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxz
+LHIscSxwLG8sbixtLGwsayxqLGk9bnVsbCxoPWIubGVuZ3RoCmlmKGghPT0wKXtyPTAKd2hpbGUoITAp
+e2lmKCEocjxoKSl7dD0iIgpzPTAKYnJlYWt9aWYoQy54Qi5XKGIscik9PT02NCl7dD1DLnhCLk5qKGIs
+MCxyKQpzPXIrMQpicmVha30rK3J9aWYoczxoJiZDLnhCLlcoYixzKT09PTkxKXtmb3IocT1zLHA9LTE7
+cTxoOysrcSl7bz1DLnhCLlcoYixxKQppZihvPT09MzcmJnA8MCl7bj1DLnhCLlFpKGIsIjI1IixxKzEp
+P3ErMjpxCnA9cQpxPW59ZWxzZSBpZihvPT09OTMpYnJlYWt9aWYocT09PWgpdGhyb3cgSC5iKFAucnIo
+IkludmFsaWQgSVB2NiBob3N0IGVudHJ5LiIsYixzKSkKbT1wPDA/cTpwClAuZWcoYixzKzEsbSk7Kytx
+CmlmKHEhPT1oJiZDLnhCLlcoYixxKSE9PTU4KXRocm93IEguYihQLnJyKCJJbnZhbGlkIGVuZCBvZiBh
+dXRob3JpdHkiLGIscSkpfWVsc2UgcT1zCndoaWxlKCEwKXtpZighKHE8aCkpe2w9aQpicmVha31pZihD
+LnhCLlcoYixxKT09PTU4KXtrPUMueEIuRyhiLHErMSkKbD1rLmxlbmd0aCE9PTA/UC5RQShrLGkpOmkK
+YnJlYWt9KytxfWo9Qy54Qi5OaihiLHMscSl9ZWxzZXtsPWkKaj1sCnQ9IiJ9cmV0dXJuIFAuS0woaixp
+LEguVk0oYy5zcGxpdCgiLyIpLHUucyksbCxkLGEsdCl9LAprRTpmdW5jdGlvbihhLGIpe3ZhciB0LHMs
+cixxLHAKZm9yKHQ9YS5sZW5ndGgscz0wO3M8dDsrK3Mpe3I9YVtzXQpyLnRvU3RyaW5nCnE9Si5VNihy
+KQpwPXEuZ0EocikKaWYoMD5wKUgudmgoUC5URSgwLDAscS5nQShyKSxudWxsLG51bGwpKQppZihILm0y
+KHIsIi8iLDApKXt0PVAuTDQoIklsbGVnYWwgcGF0aCBjaGFyYWN0ZXIgIitILkVqKHIpKQp0aHJvdyBI
+LmIodCl9fX0sCkhOOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIKZm9yKHQ9SC5xQyhhLGMsbnVsbCxI
+LnQ2KGEpLmMpLHQ9bmV3IEguYTcodCx0LmdBKHQpLHQuJHRpLkMoImE3PGFMLkU+IikpO3QuRigpOyl7
+cz10LmQKcj1QLm51KCdbIiovOjw+P1xcXFx8XScpCnMudG9TdHJpbmcKaWYoSC5tMihzLHIsMCkpe3Q9
+UC5MNCgiSWxsZWdhbCBjaGFyYWN0ZXIgaW4gcGF0aDogIitzKQp0aHJvdyBILmIodCl9fX0sCnJnOmZ1
+bmN0aW9uKGEsYil7dmFyIHQKaWYoISg2NTw9YSYmYTw9OTApKXQ9OTc8PWEmJmE8PTEyMgplbHNlIHQ9
+ITAKaWYodClyZXR1cm4KdD1QLkw0KCJJbGxlZ2FsIGRyaXZlIGxldHRlciAiK1AuT28oYSkpCnRocm93
+IEguYih0KX0sCndCOmZ1bmN0aW9uKGEsYil7aWYoYSE9bnVsbCYmYT09PVAud0soYikpcmV0dXJuIG51
+bGwKcmV0dXJuIGF9LApPZTpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxzLHIscSxwLG8KaWYoYT09bnVs
+bClyZXR1cm4gbnVsbAppZihiPT09YylyZXR1cm4iIgppZihDLnhCLm0oYSxiKT09PTkxKXt0PWMtMQpp
+ZihDLnhCLm0oYSx0KSE9PTkzKVAuUjMoYSxiLCJNaXNzaW5nIGVuZCBgXWAgdG8gbWF0Y2ggYFtgIGlu
+IGhvc3QiKQpzPWIrMQpyPVAudG8oYSxzLHQpCmlmKHI8dCl7cT1yKzEKcD1QLk9BKGEsQy54Qi5RaShh
+LCIyNSIscSk/ciszOnEsdCwiJTI1Iil9ZWxzZSBwPSIiClAuZWcoYSxzLHIpCnJldHVybiBDLnhCLk5q
+KGEsYixyKS50b0xvd2VyQ2FzZSgpK3ArIl0ifWZvcihvPWI7bzxjOysrbylpZihDLnhCLm0oYSxvKT09
+PTU4KXtyPUMueEIuWFUoYSwiJSIsYikKcj1yPj1iJiZyPGM/cjpjCmlmKHI8Yyl7cT1yKzEKcD1QLk9B
+KGEsQy54Qi5RaShhLCIyNSIscSk/ciszOnEsYywiJTI1Iil9ZWxzZSBwPSIiClAuZWcoYSxiLHIpCnJl
+dHVybiJbIitDLnhCLk5qKGEsYixyKStwKyJdIn1yZXR1cm4gUC5PTChhLGIsYyl9LAp0bzpmdW5jdGlv
+bihhLGIsYyl7dmFyIHQ9Qy54Qi5YVShhLCIlIixiKQpyZXR1cm4gdD49YiYmdDxjP3Q6Y30sCk9BOmZ1
+bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGo9ZCE9PSIiP25ldyBQLlJuKGQp
+Om51bGwKZm9yKHQ9YixzPXQscj0hMDt0PGM7KXtxPUMueEIubShhLHQpCmlmKHE9PT0zNyl7cD1QLnJ2
+KGEsdCwhMCkKbz1wPT1udWxsCmlmKG8mJnIpe3QrPTMKY29udGludWV9aWYoaj09bnVsbClqPW5ldyBQ
+LlJuKCIiKQpuPWouYSs9Qy54Qi5OaihhLHMsdCkKaWYobylwPUMueEIuTmooYSx0LHQrMykKZWxzZSBp
+ZihwPT09IiUiKVAuUjMoYSx0LCJab25lSUQgc2hvdWxkIG5vdCBjb250YWluICUgYW55bW9yZSIpCmou
+YT1uK3AKdCs9MwpzPXQKcj0hMH1lbHNle2lmKHE8MTI3KXtvPXE+Pj40CmlmKG8+PTgpcmV0dXJuIEgu
+T0goQy5GMyxvKQpvPShDLkYzW29dJjE8PChxJjE1KSkhPT0wfWVsc2Ugbz0hMQppZihvKXtpZihyJiY2
+NTw9cSYmOTA+PXEpe2lmKGo9PW51bGwpaj1uZXcgUC5SbigiIikKaWYoczx0KXtqLmErPUMueEIuTmoo
+YSxzLHQpCnM9dH1yPSExfSsrdH1lbHNle2lmKChxJjY0NTEyKT09PTU1Mjk2JiZ0KzE8Yyl7bT1DLnhC
+Lm0oYSx0KzEpCmlmKChtJjY0NTEyKT09PTU2MzIwKXtxPTY1NTM2fChxJjEwMjMpPDwxMHxtJjEwMjMK
+bD0yfWVsc2UgbD0xfWVsc2UgbD0xCms9Qy54Qi5OaihhLHMsdCkKaWYoaj09bnVsbCl7aj1uZXcgUC5S
+bigiIikKbz1qfWVsc2Ugbz1qCm8uYSs9awpvLmErPVAuelgocSkKdCs9bApzPXR9fX1pZihqPT1udWxs
+KXJldHVybiBDLnhCLk5qKGEsYixjKQppZihzPGMpai5hKz1DLnhCLk5qKGEscyxjKQpvPWouYQpyZXR1
+cm4gby5jaGFyQ29kZUF0KDApPT0wP286b30sCk9MOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscSxw
+LG8sbixtLGwsayxqCmZvcih0PWIscz10LHI9bnVsbCxxPSEwO3Q8Yzspe3A9Qy54Qi5tKGEsdCkKaWYo
+cD09PTM3KXtvPVAucnYoYSx0LCEwKQpuPW89PW51bGwKaWYobiYmcSl7dCs9Mwpjb250aW51ZX1pZihy
+PT1udWxsKXI9bmV3IFAuUm4oIiIpCm09Qy54Qi5OaihhLHMsdCkKbD1yLmErPSFxP20udG9Mb3dlckNh
+c2UoKTptCmlmKG4pe289Qy54Qi5OaihhLHQsdCszKQprPTN9ZWxzZSBpZihvPT09IiUiKXtvPSIlMjUi
+Cms9MX1lbHNlIGs9MwpyLmE9bCtvCnQrPWsKcz10CnE9ITB9ZWxzZXtpZihwPDEyNyl7bj1wPj4+NApp
+ZihuPj04KXJldHVybiBILk9IKEMuZWEsbikKbj0oQy5lYVtuXSYxPDwocCYxNSkpIT09MH1lbHNlIG49
+ITEKaWYobil7aWYocSYmNjU8PXAmJjkwPj1wKXtpZihyPT1udWxsKXI9bmV3IFAuUm4oIiIpCmlmKHM8
+dCl7ci5hKz1DLnhCLk5qKGEscyx0KQpzPXR9cT0hMX0rK3R9ZWxzZXtpZihwPD05Myl7bj1wPj4+NApp
+ZihuPj04KXJldHVybiBILk9IKEMuYWssbikKbj0oQy5ha1tuXSYxPDwocCYxNSkpIT09MH1lbHNlIG49
+ITEKaWYobilQLlIzKGEsdCwiSW52YWxpZCBjaGFyYWN0ZXIiKQplbHNle2lmKChwJjY0NTEyKT09PTU1
+Mjk2JiZ0KzE8Yyl7aj1DLnhCLm0oYSx0KzEpCmlmKChqJjY0NTEyKT09PTU2MzIwKXtwPTY1NTM2fChw
+JjEwMjMpPDwxMHxqJjEwMjMKaz0yfWVsc2Ugaz0xfWVsc2Ugaz0xCm09Qy54Qi5OaihhLHMsdCkKaWYo
+IXEpbT1tLnRvTG93ZXJDYXNlKCkKaWYocj09bnVsbCl7cj1uZXcgUC5SbigiIikKbj1yfWVsc2Ugbj1y
+Cm4uYSs9bQpuLmErPVAuelgocCkKdCs9awpzPXR9fX19aWYocj09bnVsbClyZXR1cm4gQy54Qi5Oaihh
+LGIsYykKaWYoczxjKXttPUMueEIuTmooYSxzLGMpCnIuYSs9IXE/bS50b0xvd2VyQ2FzZSgpOm19bj1y
+LmEKcmV0dXJuIG4uY2hhckNvZGVBdCgwKT09MD9uOm59LApQaTpmdW5jdGlvbihhLGIsYyl7dmFyIHQs
+cyxyLHEKaWYoYj09PWMpcmV0dXJuIiIKaWYoIVAuRXQoSi5yWShhKS5XKGEsYikpKVAuUjMoYSxiLCJT
+Y2hlbWUgbm90IHN0YXJ0aW5nIHdpdGggYWxwaGFiZXRpYyBjaGFyYWN0ZXIiKQpmb3IodD1iLHM9ITE7
+dDxjOysrdCl7cj1DLnhCLlcoYSx0KQppZihyPDEyOCl7cT1yPj4+NAppZihxPj04KXJldHVybiBILk9I
+KEMubUsscSkKcT0oQy5tS1txXSYxPDwociYxNSkpIT09MH1lbHNlIHE9ITEKaWYoIXEpUC5SMyhhLHQs
+IklsbGVnYWwgc2NoZW1lIGNoYXJhY3RlciIpCmlmKDY1PD1yJiZyPD05MClzPSEwfWE9Qy54Qi5Oaihh
+LGIsYykKcmV0dXJuIFAuWWEocz9hLnRvTG93ZXJDYXNlKCk6YSl9LApZYTpmdW5jdGlvbihhKXtpZihh
+PT09Imh0dHAiKXJldHVybiJodHRwIgppZihhPT09ImZpbGUiKXJldHVybiJmaWxlIgppZihhPT09Imh0
+dHBzIilyZXR1cm4iaHR0cHMiCmlmKGE9PT0icGFja2FnZSIpcmV0dXJuInBhY2thZ2UiCnJldHVybiBh
+fSwKelI6ZnVuY3Rpb24oYSxiLGMpe2lmKGE9PW51bGwpcmV0dXJuIiIKcmV0dXJuIFAuUEkoYSxiLGMs
+Qy50bywhMSl9LAprYTpmdW5jdGlvbihhLGIsYyxkLGUsZil7dmFyIHQscyxyPWU9PT0iZmlsZSIscT1y
+fHxmCmlmKGE9PW51bGwpe2lmKGQ9PW51bGwpcmV0dXJuIHI/Ii8iOiIiCnQ9SC50NihkKQpzPW5ldyBI
+LmxKKGQsdC5DKCJxVSgxKSIpLmEobmV3IFAuUlooKSksdC5DKCJsSjwxLHFVPiIpKS56VigwLCIvIil9
+ZWxzZSBpZihkIT1udWxsKXRocm93IEguYihQLnhZKCJCb3RoIHBhdGggYW5kIHBhdGhTZWdtZW50cyBz
+cGVjaWZpZWQiKSkKZWxzZSBzPVAuUEkoYSxiLGMsQy5XZCwhMCkKaWYocy5sZW5ndGg9PT0wKXtpZihy
+KXJldHVybiIvIn1lbHNlIGlmKHEmJiFDLnhCLm4ocywiLyIpKXM9Ii8iK3MKcmV0dXJuIFAuSnIocyxl
+LGYpfSwKSnI6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PWIubGVuZ3RoPT09MAppZih0JiYhYyYmIUMueEIu
+bihhLCIvIikpcmV0dXJuIFAud0YoYSwhdHx8YykKcmV0dXJuIFAueGUoYSl9LApsZTpmdW5jdGlvbihh
+LGIsYyxkKXt2YXIgdCxzPXt9CmlmKGEhPW51bGwpe2lmKGQhPW51bGwpdGhyb3cgSC5iKFAueFkoIkJv
+dGggcXVlcnkgYW5kIHF1ZXJ5UGFyYW1ldGVycyBzcGVjaWZpZWQiKSkKcmV0dXJuIFAuUEkoYSxiLGMs
+Qy5WQywhMCl9aWYoZD09bnVsbClyZXR1cm4gbnVsbAp0PW5ldyBQLlJuKCIiKQpzLmE9IiIKZC5LKDAs
+bmV3IFAueTUobmV3IFAuTUUocyx0KSkpCnM9dC5hCnJldHVybiBzLmNoYXJDb2RlQXQoMCk9PTA/czpz
+fSwKdEc6ZnVuY3Rpb24oYSxiLGMpe2lmKGE9PW51bGwpcmV0dXJuIG51bGwKcmV0dXJuIFAuUEkoYSxi
+LGMsQy5WQywhMCl9LApydjpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEscCxvPWIrMgppZihvPj1h
+Lmxlbmd0aClyZXR1cm4iJSIKdD1DLnhCLm0oYSxiKzEpCnM9Qy54Qi5tKGEsbykKcj1ILm9vKHQpCnE9
+SC5vbyhzKQppZihyPDB8fHE8MClyZXR1cm4iJSIKcD1yKjE2K3EKaWYocDwxMjcpe289Qy5qbi53Ryhw
+LDQpCmlmKG8+PTgpcmV0dXJuIEguT0goQy5GMyxvKQpvPShDLkYzW29dJjE8PChwJjE1KSkhPT0wfWVs
+c2Ugbz0hMQppZihvKXJldHVybiBILkx3KGMmJjY1PD1wJiY5MD49cD8ocHwzMik+Pj4wOnApCmlmKHQ+
+PTk3fHxzPj05NylyZXR1cm4gQy54Qi5OaihhLGIsYiszKS50b1VwcGVyQ2FzZSgpCnJldHVybiBudWxs
+fSwKelg6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG4sbSxsPSIwMTIzNDU2Nzg5QUJDREVGIgpp
+ZihhPDEyOCl7dD1uZXcgVWludDhBcnJheSgzKQpzPXQubGVuZ3RoCmlmKDA+PXMpcmV0dXJuIEguT0go
+dCwwKQp0WzBdPTM3CnI9Qy54Qi5XKGwsYT4+PjQpCmlmKDE+PXMpcmV0dXJuIEguT0godCwxKQp0WzFd
+PXIKcj1DLnhCLlcobCxhJjE1KQppZigyPj1zKXJldHVybiBILk9IKHQsMikKdFsyXT1yfWVsc2V7aWYo
+YT4yMDQ3KWlmKGE+NjU1MzUpe3E9MjQwCnA9NH1lbHNle3E9MjI0CnA9M31lbHNle3E9MTkyCnA9Mn10
+PW5ldyBVaW50OEFycmF5KDMqcCkKZm9yKHM9dC5sZW5ndGgsbz0wOy0tcCxwPj0wO3E9MTI4KXtuPUMu
+am4uYmYoYSw2KnApJjYzfHEKaWYobz49cylyZXR1cm4gSC5PSCh0LG8pCnRbb109MzcKcj1vKzEKbT1D
+LnhCLlcobCxuPj4+NCkKaWYocj49cylyZXR1cm4gSC5PSCh0LHIpCnRbcl09bQptPW8rMgpyPUMueEIu
+VyhsLG4mMTUpCmlmKG0+PXMpcmV0dXJuIEguT0godCxtKQp0W21dPXIKbys9M319cmV0dXJuIFAuSE0o
+dCwwLG51bGwpfSwKUEk6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgdD1QLlVsKGEsYixjLGQsZSkKcmV0
+dXJuIHQ9PW51bGw/Qy54Qi5OaihhLGIsYyk6dH0sClVsOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHQs
+cyxyLHEscCxvLG4sbSxsLGs9bnVsbApmb3IodD0hZSxzPWIscj1zLHE9aztzPGM7KXtwPUMueEIubShh
+LHMpCmlmKHA8MTI3KXtvPXA+Pj40CmlmKG8+PTgpcmV0dXJuIEguT0goZCxvKQpvPShkW29dJjE8PChw
+JjE1KSkhPT0wfWVsc2Ugbz0hMQppZihvKSsrcwplbHNle2lmKHA9PT0zNyl7bj1QLnJ2KGEscywhMSkK
+aWYobj09bnVsbCl7cys9Mwpjb250aW51ZX1pZigiJSI9PT1uKXtuPSIlMjUiCm09MX1lbHNlIG09M31l
+bHNle2lmKHQpaWYocDw9OTMpe289cD4+PjQKaWYobz49OClyZXR1cm4gSC5PSChDLmFrLG8pCm89KEMu
+YWtbb10mMTw8KHAmMTUpKSE9PTB9ZWxzZSBvPSExCmVsc2Ugbz0hMQppZihvKXtQLlIzKGEscywiSW52
+YWxpZCBjaGFyYWN0ZXIiKQptPWsKbj1tfWVsc2V7aWYoKHAmNjQ1MTIpPT09NTUyOTYpe289cysxCmlm
+KG88Yyl7bD1DLnhCLm0oYSxvKQppZigobCY2NDUxMik9PT01NjMyMCl7cD02NTUzNnwocCYxMDIzKTw8
+MTB8bCYxMDIzCm09Mn1lbHNlIG09MX1lbHNlIG09MX1lbHNlIG09MQpuPVAuelgocCl9fWlmKHE9PW51
+bGwpe3E9bmV3IFAuUm4oIiIpCm89cX1lbHNlIG89cQpvLmErPUMueEIuTmooYSxyLHMpCm8uYSs9SC5F
+aihuKQppZih0eXBlb2YgbSE9PSJudW1iZXIiKXJldHVybiBILnBZKG0pCnMrPW0Kcj1zfX1pZihxPT1u
+dWxsKXJldHVybiBrCmlmKHI8YylxLmErPUMueEIuTmooYSxyLGMpCnQ9cS5hCnJldHVybiB0LmNoYXJD
+b2RlQXQoMCk9PTA/dDp0fSwKeUI6ZnVuY3Rpb24oYSl7aWYoQy54Qi5uKGEsIi4iKSlyZXR1cm4hMApy
+ZXR1cm4gQy54Qi5PWShhLCIvLiIpIT09LTF9LAp4ZTpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8s
+bgppZighUC55QihhKSlyZXR1cm4gYQp0PUguVk0oW10sdS5zKQpmb3Iocz1hLnNwbGl0KCIvIikscj1z
+Lmxlbmd0aCxxPSExLHA9MDtwPHI7KytwKXtvPXNbcF0KaWYoSi5STShvLCIuLiIpKXtuPXQubGVuZ3Ro
+CmlmKG4hPT0wKXtpZigwPj1uKXJldHVybiBILk9IKHQsLTEpCnQucG9wKCkKaWYodC5sZW5ndGg9PT0w
+KUMuTm0uaSh0LCIiKX1xPSEwfWVsc2UgaWYoIi4iPT09bylxPSEwCmVsc2V7Qy5ObS5pKHQsbykKcT0h
+MX19aWYocSlDLk5tLmkodCwiIikKcmV0dXJuIEMuTm0uelYodCwiLyIpfSwKd0Y6ZnVuY3Rpb24oYSxi
+KXt2YXIgdCxzLHIscSxwLG8KaWYoIVAueUIoYSkpcmV0dXJuIWI/UC5DMShhKTphCnQ9SC5WTShbXSx1
+LnMpCmZvcihzPWEuc3BsaXQoIi8iKSxyPXMubGVuZ3RoLHE9ITEscD0wO3A8cjsrK3Ape289c1twXQpp
+ZigiLi4iPT09bylpZih0Lmxlbmd0aCE9PTAmJkMuTm0uZ3JaKHQpIT09Ii4uIil7aWYoMD49dC5sZW5n
+dGgpcmV0dXJuIEguT0godCwtMSkKdC5wb3AoKQpxPSEwfWVsc2V7Qy5ObS5pKHQsIi4uIikKcT0hMX1l
+bHNlIGlmKCIuIj09PW8pcT0hMAplbHNle0MuTm0uaSh0LG8pCnE9ITF9fXM9dC5sZW5ndGgKaWYocyE9
+PTApaWYocz09PTEpe2lmKDA+PXMpcmV0dXJuIEguT0godCwwKQpzPXRbMF0ubGVuZ3RoPT09MH1lbHNl
+IHM9ITEKZWxzZSBzPSEwCmlmKHMpcmV0dXJuIi4vIgppZihxfHxDLk5tLmdyWih0KT09PSIuLiIpQy5O
+bS5pKHQsIiIpCmlmKCFiKXtpZigwPj10Lmxlbmd0aClyZXR1cm4gSC5PSCh0LDApCkMuTm0uWSh0LDAs
+UC5DMSh0WzBdKSl9cmV0dXJuIEMuTm0uelYodCwiLyIpfSwKQzE6ZnVuY3Rpb24oYSl7dmFyIHQscyxy
+LHE9YS5sZW5ndGgKaWYocT49MiYmUC5FdChKLlF6KGEsMCkpKWZvcih0PTE7dDxxOysrdCl7cz1DLnhC
+LlcoYSx0KQppZihzPT09NTgpcmV0dXJuIEMueEIuTmooYSwwLHQpKyIlM0EiK0MueEIuRyhhLHQrMSkK
+aWYoczw9MTI3KXtyPXM+Pj40CmlmKHI+PTgpcmV0dXJuIEguT0goQy5tSyxyKQpyPShDLm1LW3JdJjE8
+PChzJjE1KSk9PT0wfWVsc2Ugcj0hMAppZihyKWJyZWFrfXJldHVybiBhfSwKbW46ZnVuY3Rpb24oYSl7
+dmFyIHQscyxyLHE9YS5nRmooKSxwPXEubGVuZ3RoCmlmKHA+MCYmSi5IbShxWzBdKT09PTImJkouYTYo
+cVswXSwxKT09PTU4KXtpZigwPj1wKXJldHVybiBILk9IKHEsMCkKUC5yZyhKLmE2KHFbMF0sMCksITEp
+ClAuSE4ocSwhMSwxKQp0PSEwfWVsc2V7UC5ITihxLCExLDApCnQ9ITF9cz1hLmd0VCgpJiYhdD8iIisi
+XFwiOiIiCmlmKGEuZ2NqKCkpe3I9YS5nSmYoYSkKaWYoci5sZW5ndGghPT0wKXM9cysiXFwiK3IrIlxc
+In1zPVAudmcocyxxLCJcXCIpCnA9dCYmcD09PTE/cysiXFwiOnMKcmV0dXJuIHAuY2hhckNvZGVBdCgw
+KT09MD9wOnB9LApJaDpmdW5jdGlvbihhLGIpe3ZhciB0LHMscgpmb3IodD0wLHM9MDtzPDI7KytzKXty
+PUMueEIuVyhhLGIrcykKaWYoNDg8PXImJnI8PTU3KXQ9dCoxNityLTQ4CmVsc2V7cnw9MzIKaWYoOTc8
+PXImJnI8PTEwMil0PXQqMTYrci04NwplbHNlIHRocm93IEguYihQLnhZKCJJbnZhbGlkIFVSTCBlbmNv
+ZGluZyIpKX19cmV0dXJuIHR9LAprdTpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciB0LHMscixxLHA9Si5y
+WShhKSxvPWIKd2hpbGUoITApe2lmKCEobzxjKSl7dD0hMApicmVha31zPXAuVyhhLG8pCmlmKHM8PTEy
+NylpZihzIT09Mzcpcj1lJiZzPT09NDMKZWxzZSByPSEwCmVsc2Ugcj0hMAppZihyKXt0PSExCmJyZWFr
+fSsrb31pZih0KXtpZihDLnhNIT09ZClyPSExCmVsc2Ugcj0hMAppZihyKXJldHVybiBwLk5qKGEsYixj
+KQplbHNlIHE9bmV3IEgucWoocC5OaihhLGIsYykpfWVsc2V7cT1ILlZNKFtdLHUudCkKZm9yKG89Yjtv
+PGM7KytvKXtzPXAuVyhhLG8pCmlmKHM+MTI3KXRocm93IEguYihQLnhZKCJJbGxlZ2FsIHBlcmNlbnQg
+ZW5jb2RpbmcgaW4gVVJJIikpCmlmKHM9PT0zNyl7aWYobyszPmEubGVuZ3RoKXRocm93IEguYihQLnhZ
+KCJUcnVuY2F0ZWQgVVJJIikpCkMuTm0uaShxLFAuSWgoYSxvKzEpKQpvKz0yfWVsc2UgaWYoZSYmcz09
+PTQzKUMuTm0uaShxLDMyKQplbHNlIEMuTm0uaShxLHMpfX11LkwuYShxKQpyZXR1cm4gbmV3IFAuR1ko
+ITEpLldKKHEpfSwKRXQ6ZnVuY3Rpb24oYSl7dmFyIHQ9YXwzMgpyZXR1cm4gOTc8PXQmJnQ8PTEyMn0s
+CktEOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscSxwLG8sbixtLGw9IkludmFsaWQgTUlNRSB0eXBl
+IixrPUguVk0oW2ItMV0sdS50KQpmb3IodD1hLmxlbmd0aCxzPWIscj0tMSxxPW51bGw7czx0Oysrcyl7
+cT1DLnhCLlcoYSxzKQppZihxPT09NDR8fHE9PT01OSlicmVhawppZihxPT09NDcpe2lmKHI8MCl7cj1z
+CmNvbnRpbnVlfXRocm93IEguYihQLnJyKGwsYSxzKSl9fWlmKHI8MCYmcz5iKXRocm93IEguYihQLnJy
+KGwsYSxzKSkKZm9yKDtxIT09NDQ7KXtDLk5tLmkoayxzKTsrK3MKZm9yKHA9LTE7czx0Oysrcyl7cT1D
+LnhCLlcoYSxzKQppZihxPT09NjEpe2lmKHA8MClwPXN9ZWxzZSBpZihxPT09NTl8fHE9PT00NClicmVh
+a31pZihwPj0wKUMuTm0uaShrLHApCmVsc2V7bz1DLk5tLmdyWihrKQppZihxIT09NDR8fHMhPT1vKzd8
+fCFDLnhCLlFpKGEsImJhc2U2NCIsbysxKSl0aHJvdyBILmIoUC5ycigiRXhwZWN0aW5nICc9JyIsYSxz
+KSkKYnJlYWt9fUMuTm0uaShrLHMpCm49cysxCmlmKChrLmxlbmd0aCYxKT09PTEpYT1DLmg5LnlyKGEs
+bix0KQplbHNle209UC5VbChhLG4sdCxDLlZDLCEwKQppZihtIT1udWxsKWE9Qy54Qi5pNyhhLG4sdCxt
+KX1yZXR1cm4gbmV3IFAuUEUoYSxrLGMpfSwKS046ZnVuY3Rpb24oKXt2YXIgdD0iMDEyMzQ1Njc4OUFC
+Q0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXotLl9+ISQmJygp
+KissOz0iLHM9Ii4iLHI9IjoiLHE9Ii8iLHA9Ij8iLG89IiMiLG49dS5nYyxtPVAuZEgoMjIsbmV3IFAu
+cTMoKSwhMCxuKSxsPW5ldyBQLnlJKG0pLGs9bmV3IFAuYzYoKSxqPW5ldyBQLnFkKCksaT1uLmEobC4k
+MigwLDIyNSkpCmsuJDMoaSx0LDEpCmsuJDMoaSxzLDE0KQprLiQzKGksciwzNCkKay4kMyhpLHEsMykK
+ay4kMyhpLHAsMTcyKQprLiQzKGksbywyMDUpCmk9bi5hKGwuJDIoMTQsMjI1KSkKay4kMyhpLHQsMSkK
+ay4kMyhpLHMsMTUpCmsuJDMoaSxyLDM0KQprLiQzKGkscSwyMzQpCmsuJDMoaSxwLDE3MikKay4kMyhp
+LG8sMjA1KQppPW4uYShsLiQyKDE1LDIyNSkpCmsuJDMoaSx0LDEpCmsuJDMoaSwiJSIsMjI1KQprLiQz
+KGksciwzNCkKay4kMyhpLHEsOSkKay4kMyhpLHAsMTcyKQprLiQzKGksbywyMDUpCmk9bi5hKGwuJDIo
+MSwyMjUpKQprLiQzKGksdCwxKQprLiQzKGksciwzNCkKay4kMyhpLHEsMTApCmsuJDMoaSxwLDE3MikK
+ay4kMyhpLG8sMjA1KQppPW4uYShsLiQyKDIsMjM1KSkKay4kMyhpLHQsMTM5KQprLiQzKGkscSwxMzEp
+CmsuJDMoaSxzLDE0NikKay4kMyhpLHAsMTcyKQprLiQzKGksbywyMDUpCmk9bi5hKGwuJDIoMywyMzUp
+KQprLiQzKGksdCwxMSkKay4kMyhpLHEsNjgpCmsuJDMoaSxzLDE4KQprLiQzKGkscCwxNzIpCmsuJDMo
+aSxvLDIwNSkKaT1uLmEobC4kMig0LDIyOSkpCmsuJDMoaSx0LDUpCmouJDMoaSwiQVoiLDIyOSkKay4k
+MyhpLHIsMTAyKQprLiQzKGksIkAiLDY4KQprLiQzKGksIlsiLDIzMikKay4kMyhpLHEsMTM4KQprLiQz
+KGkscCwxNzIpCmsuJDMoaSxvLDIwNSkKaT1uLmEobC4kMig1LDIyOSkpCmsuJDMoaSx0LDUpCmouJDMo
+aSwiQVoiLDIyOSkKay4kMyhpLHIsMTAyKQprLiQzKGksIkAiLDY4KQprLiQzKGkscSwxMzgpCmsuJDMo
+aSxwLDE3MikKay4kMyhpLG8sMjA1KQppPW4uYShsLiQyKDYsMjMxKSkKai4kMyhpLCIxOSIsNykKay4k
+MyhpLCJAIiw2OCkKay4kMyhpLHEsMTM4KQprLiQzKGkscCwxNzIpCmsuJDMoaSxvLDIwNSkKaT1uLmEo
+bC4kMig3LDIzMSkpCmouJDMoaSwiMDkiLDcpCmsuJDMoaSwiQCIsNjgpCmsuJDMoaSxxLDEzOCkKay4k
+MyhpLHAsMTcyKQprLiQzKGksbywyMDUpCmsuJDMobi5hKGwuJDIoOCw4KSksIl0iLDUpCmk9bi5hKGwu
+JDIoOSwyMzUpKQprLiQzKGksdCwxMSkKay4kMyhpLHMsMTYpCmsuJDMoaSxxLDIzNCkKay4kMyhpLHAs
+MTcyKQprLiQzKGksbywyMDUpCmk9bi5hKGwuJDIoMTYsMjM1KSkKay4kMyhpLHQsMTEpCmsuJDMoaSxz
+LDE3KQprLiQzKGkscSwyMzQpCmsuJDMoaSxwLDE3MikKay4kMyhpLG8sMjA1KQppPW4uYShsLiQyKDE3
+LDIzNSkpCmsuJDMoaSx0LDExKQprLiQzKGkscSw5KQprLiQzKGkscCwxNzIpCmsuJDMoaSxvLDIwNSkK
+aT1uLmEobC4kMigxMCwyMzUpKQprLiQzKGksdCwxMSkKay4kMyhpLHMsMTgpCmsuJDMoaSxxLDIzNCkK
+ay4kMyhpLHAsMTcyKQprLiQzKGksbywyMDUpCmk9bi5hKGwuJDIoMTgsMjM1KSkKay4kMyhpLHQsMTEp
+CmsuJDMoaSxzLDE5KQprLiQzKGkscSwyMzQpCmsuJDMoaSxwLDE3MikKay4kMyhpLG8sMjA1KQppPW4u
+YShsLiQyKDE5LDIzNSkpCmsuJDMoaSx0LDExKQprLiQzKGkscSwyMzQpCmsuJDMoaSxwLDE3MikKay4k
+MyhpLG8sMjA1KQppPW4uYShsLiQyKDExLDIzNSkpCmsuJDMoaSx0LDExKQprLiQzKGkscSwxMCkKay4k
+MyhpLHAsMTcyKQprLiQzKGksbywyMDUpCmk9bi5hKGwuJDIoMTIsMjM2KSkKay4kMyhpLHQsMTIpCmsu
+JDMoaSxwLDEyKQprLiQzKGksbywyMDUpCmk9bi5hKGwuJDIoMTMsMjM3KSkKay4kMyhpLHQsMTMpCmsu
+JDMoaSxwLDEzKQpqLiQzKG4uYShsLiQyKDIwLDI0NSkpLCJheiIsMjEpCmw9bi5hKGwuJDIoMjEsMjQ1
+KSkKai4kMyhsLCJheiIsMjEpCmouJDMobCwiMDkiLDIxKQprLiQzKGwsIistLiIsMjEpCnJldHVybiBt
+fSwKVUI6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgdCxzLHIscSxwLG89JC52WigpCmZvcih0PUouclko
+YSkscz1iO3M8YzsrK3Mpe2lmKGQ8MHx8ZD49by5sZW5ndGgpcmV0dXJuIEguT0gobyxkKQpyPW9bZF0K
+cT10LlcoYSxzKV45NgppZihxPjk1KXE9MzEKaWYocT49ci5sZW5ndGgpcmV0dXJuIEguT0gocixxKQpw
+PXJbcV0KZD1wJjMxCkMuTm0uWShlLHA+Pj41LHMpfXJldHVybiBkfSwKV0Y6ZnVuY3Rpb24gV0YoYSxi
+KXt0aGlzLmE9YQp0aGlzLmI9Yn0sCmEyOmZ1bmN0aW9uIGEyKCl7fSwKaVA6ZnVuY3Rpb24gaVAoYSxi
+KXt0aGlzLmE9YQp0aGlzLmI9Yn0sCkNQOmZ1bmN0aW9uIENQKCl7fSwKWFM6ZnVuY3Rpb24gWFMoKXt9
+LApDNjpmdW5jdGlvbiBDNihhKXt0aGlzLmE9YX0sCm46ZnVuY3Rpb24gbigpe30sCnU6ZnVuY3Rpb24g
+dShhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kfSwKYko6ZnVuY3Rpb24g
+YkooYSxiLGMsZCxlLGYpe3ZhciBfPXRoaXMKXy5lPWEKXy5mPWIKXy5hPWMKXy5iPWQKXy5jPWUKXy5k
+PWZ9LAplWTpmdW5jdGlvbiBlWShhLGIsYyxkLGUpe3ZhciBfPXRoaXMKXy5mPWEKXy5hPWIKXy5iPWMK
+Xy5jPWQKXy5kPWV9LAptcDpmdW5jdGlvbiBtcChhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1i
+Cl8uYz1jCl8uZD1kfSwKdWI6ZnVuY3Rpb24gdWIoYSl7dGhpcy5hPWF9LApkczpmdW5jdGlvbiBkcyhh
+KXt0aGlzLmE9YX0sCmxqOmZ1bmN0aW9uIGxqKGEpe3RoaXMuYT1hfSwKVVY6ZnVuY3Rpb24gVVYoYSl7
+dGhpcy5hPWF9LAprNTpmdW5jdGlvbiBrNSgpe30sCktZOmZ1bmN0aW9uIEtZKCl7fSwKYzpmdW5jdGlv
+biBjKGEpe3RoaXMuYT1hfSwKQ0Q6ZnVuY3Rpb24gQ0QoYSl7dGhpcy5hPWF9LAphRTpmdW5jdGlvbiBh
+RShhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApFSDpmdW5jdGlvbiBFSCgpe30sCklm
+OmZ1bmN0aW9uIElmKCl7fSwKY1g6ZnVuY3Rpb24gY1goKXt9LApBbjpmdW5jdGlvbiBBbigpe30sCnpN
+OmZ1bmN0aW9uIHpNKCl7fSwKWjA6ZnVuY3Rpb24gWjAoKXt9LApOMzpmdW5jdGlvbiBOMyhhLGIsYyl7
+dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy4kdGk9Y30sCmM4OmZ1bmN0aW9uIGM4KCl7fSwKbGY6ZnVuY3Rp
+b24gbGYoKXt9LApNaDpmdW5jdGlvbiBNaCgpe30sCk9kOmZ1bmN0aW9uIE9kKCl7fSwKaWI6ZnVuY3Rp
+b24gaWIoKXt9LAp4dTpmdW5jdGlvbiB4dSgpe30sCkd6OmZ1bmN0aW9uIEd6KCl7fSwKWmQ6ZnVuY3Rp
+b24gWmQoKXt9LApxVTpmdW5jdGlvbiBxVSgpe30sClJuOmZ1bmN0aW9uIFJuKGEpe3RoaXMuYT1hfSwK
+R0Q6ZnVuY3Rpb24gR0QoKXt9LApuMTpmdW5jdGlvbiBuMShhKXt0aGlzLmE9YX0sCmNTOmZ1bmN0aW9u
+IGNTKGEpe3RoaXMuYT1hfSwKVkM6ZnVuY3Rpb24gVkMoYSl7dGhpcy5hPWF9LApKVDpmdW5jdGlvbiBK
+VChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKRG46ZnVuY3Rpb24gRG4oYSxiLGMsZCxlLGYsZyl7dmFy
+IF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZApfLmU9ZQpfLmY9ZgpfLnI9ZwpfLlE9Xy56PV8u
+eT1fLng9bnVsbH0sClJaOmZ1bmN0aW9uIFJaKCl7fSwKTUU6ZnVuY3Rpb24gTUUoYSxiKXt0aGlzLmE9
+YQp0aGlzLmI9Yn0sCnk1OmZ1bmN0aW9uIHk1KGEpe3RoaXMuYT1hfSwKUEU6ZnVuY3Rpb24gUEUoYSxi
+LGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKcTM6ZnVuY3Rpb24gcTMoKXt9LAp5STpmdW5j
+dGlvbiB5SShhKXt0aGlzLmE9YX0sCmM2OmZ1bmN0aW9uIGM2KCl7fSwKcWQ6ZnVuY3Rpb24gcWQoKXt9
+LApVZjpmdW5jdGlvbiBVZihhLGIsYyxkLGUsZixnLGgpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5j
+PWMKXy5kPWQKXy5lPWUKXy5mPWYKXy5yPWcKXy54PWgKXy55PW51bGx9LApxZTpmdW5jdGlvbiBxZShh
+LGIsYyxkLGUsZixnKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kCl8uZT1lCl8uZj1m
+Cl8ucj1nCl8uUT1fLno9Xy55PV8ueD1udWxsfSwKaUo6ZnVuY3Rpb24gaUooKXt9LApqZzpmdW5jdGlv
+biBqZyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKVGE6ZnVuY3Rpb24gVGEoYSxiKXt0aGlzLmE9YQp0
+aGlzLmI9Yn0sCkJmOmZ1bmN0aW9uIEJmKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApBczpmdW5jdGlv
+biBBcygpe30sCkdFOmZ1bmN0aW9uIEdFKGEpe3RoaXMuYT1hfSwKTjc6ZnVuY3Rpb24gTjcoYSxiKXt0
+aGlzLmE9YQp0aGlzLmI9Yn0sCnVROmZ1bmN0aW9uIHVRKCl7fSwKaEY6ZnVuY3Rpb24gaEYoKXt9LApS
+NDpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxzLHIKSC55OChiKQp1LmouYShkKQppZihILm9UKGIpKXt0
+PVtjXQpDLk5tLkZWKHQsZCkKZD10fXM9dS56CnI9UC5DSChKLk0xKGQsUC53MCgpLHMpLCEwLHMpCnUu
+WS5hKGEpCnJldHVybiBQLndZKEguRWsoYSxyLG51bGwpKX0sCkRtOmZ1bmN0aW9uKGEsYixjKXt2YXIg
+dAp0cnl7aWYoT2JqZWN0LmlzRXh0ZW5zaWJsZShhKSYmIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJv
+cGVydHkuY2FsbChhLGIpKXtPYmplY3QuZGVmaW5lUHJvcGVydHkoYSxiLHt2YWx1ZTpjfSkKcmV0dXJu
+ITB9fWNhdGNoKHQpe0guUnUodCl9cmV0dXJuITF9LApPbTpmdW5jdGlvbihhLGIpe2lmKE9iamVjdC5w
+cm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChhLGIpKXJldHVybiBhW2JdCnJldHVybiBudWxsfSwK
+d1k6ZnVuY3Rpb24oYSl7aWYoYT09bnVsbHx8dHlwZW9mIGE9PSJzdHJpbmcifHx0eXBlb2YgYT09Im51
+bWJlciJ8fEgubChhKSlyZXR1cm4gYQppZihhIGluc3RhbmNlb2YgUC5FNClyZXR1cm4gYS5hCmlmKEgu
+UjkoYSkpcmV0dXJuIGEKaWYodS54LmIoYSkpcmV0dXJuIGEKaWYoYSBpbnN0YW5jZW9mIFAuaVApcmV0
+dXJuIEgubzIoYSkKaWYodS5ZLmIoYSkpcmV0dXJuIFAuaEUoYSwiJGRhcnRfanNGdW5jdGlvbiIsbmV3
+IFAuUEMoKSkKcmV0dXJuIFAuaEUoYSwiXyRkYXJ0X2pzT2JqZWN0IixuZXcgUC5tdCgkLmtJKCkpKX0s
+CmhFOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1QLk9tKGEsYikKaWYodD09bnVsbCl7dD1jLiQxKGEpClAu
+RG0oYSxiLHQpfXJldHVybiB0fSwKTDc6ZnVuY3Rpb24oYSl7dmFyIHQscwppZihhPT1udWxsfHx0eXBl
+b2YgYT09InN0cmluZyJ8fHR5cGVvZiBhPT0ibnVtYmVyInx8dHlwZW9mIGE9PSJib29sZWFuIilyZXR1
+cm4gYQplbHNlIGlmKGEgaW5zdGFuY2VvZiBPYmplY3QmJkguUjkoYSkpcmV0dXJuIGEKZWxzZSBpZihh
+IGluc3RhbmNlb2YgT2JqZWN0JiZ1LnguYihhKSlyZXR1cm4gYQplbHNlIGlmKGEgaW5zdGFuY2VvZiBE
+YXRlKXt0PUgudVAoYS5nZXRUaW1lKCkpCmlmKE1hdGguYWJzKHQpPD04NjRlMTMpcz0hMQplbHNlIHM9
+ITAKaWYocylILnZoKFAueFkoIkRhdGVUaW1lIGlzIG91dHNpZGUgdmFsaWQgcmFuZ2U6ICIrdCkpClAu
+VUkoITEsImlzVXRjIix1LnkpCnJldHVybiBuZXcgUC5pUCh0LCExKX1lbHNlIGlmKGEuY29uc3RydWN0
+b3I9PT0kLmtJKCkpcmV0dXJuIGEubwplbHNlIHJldHVybiBQLk5EKGEpfSwKTkQ6ZnVuY3Rpb24oYSl7
+aWYodHlwZW9mIGE9PSJmdW5jdGlvbiIpcmV0dXJuIFAuaVEoYSwkLncoKSxuZXcgUC5OeigpKQppZihh
+IGluc3RhbmNlb2YgQXJyYXkpcmV0dXJuIFAuaVEoYSwkLlI4KCksbmV3IFAuUVMoKSkKcmV0dXJuIFAu
+aVEoYSwkLlI4KCksbmV3IFAubnAoKSl9LAppUTpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9UC5PbShhLGIp
+CmlmKHQ9PW51bGx8fCEoYSBpbnN0YW5jZW9mIE9iamVjdCkpe3Q9Yy4kMShhKQpQLkRtKGEsYix0KX1y
+ZXR1cm4gdH0sClBDOmZ1bmN0aW9uIFBDKCl7fSwKbXQ6ZnVuY3Rpb24gbXQoYSl7dGhpcy5hPWF9LApO
+ejpmdW5jdGlvbiBOeigpe30sClFTOmZ1bmN0aW9uIFFTKCl7fSwKbnA6ZnVuY3Rpb24gbnAoKXt9LApF
+NDpmdW5jdGlvbiBFNChhKXt0aGlzLmE9YX0sCnI3OmZ1bmN0aW9uIHI3KGEpe3RoaXMuYT1hfSwKVHo6
+ZnVuY3Rpb24gVHooYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKY286ZnVuY3Rpb24gY28oKXt9LApi
+QjpmdW5jdGlvbiBiQigpe30sCktlOmZ1bmN0aW9uIEtlKGEpe3RoaXMuYT1hfSwKZDU6ZnVuY3Rpb24g
+ZDUoKXt9LApuNjpmdW5jdGlvbiBuNigpe319LFc9ewp4MzpmdW5jdGlvbigpe3JldHVybiB3aW5kb3d9
+LApacjpmdW5jdGlvbigpe3JldHVybiBkb2N1bWVudH0sCko2OmZ1bmN0aW9uKCl7dmFyIHQ9ZG9jdW1l
+bnQuY3JlYXRlRWxlbWVudCgiYSIpCnJldHVybiB0fSwKVTk6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHM9
+ZG9jdW1lbnQuYm9keQpzLnRvU3RyaW5nCnQ9dS5hYwp0PW5ldyBILlU1KG5ldyBXLmU3KEMuUlkucjYo
+cyxhLGIsYykpLHQuQygiYTIobEQuRSkiKS5hKG5ldyBXLkN2KCkpLHQuQygiVTU8bEQuRT4iKSkKcmV0
+dXJuIHUuaC5hKHQuZ3I4KHQpKX0sCnJTOmZ1bmN0aW9uKGEpe3ZhciB0LHMscj0iZWxlbWVudCB0YWcg
+dW5hdmFpbGFibGUiCnRyeXt0PUouWUUoYSkKdC5nbnMoYSkKcj10LmducyhhKX1jYXRjaChzKXtILlJ1
+KHMpfXJldHVybiByfSwKcUQ6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscT1uZXcgUC52cygkLlgzLHUu
+YW8pLHA9bmV3IFAuWmYocSx1LmJqKSxvPW5ldyBYTUxIdHRwUmVxdWVzdCgpCkMuRHQuZW8obywiR0VU
+IixhLCEwKQpiLksoMCxuZXcgVy5iVShvKSkKdD11LnUKcz10LmEobmV3IFcuaEgobyxwKSkKdS5aLmEo
+bnVsbCkKcj11LkUKVy5KRShvLCJsb2FkIixzLCExLHIpClcuSkUobywiZXJyb3IiLHQuYShwLmdZSigp
+KSwhMSxyKQpvLnNlbmQoKQpyZXR1cm4gcX0sCkMwOmZ1bmN0aW9uKGEsYil7YT01MzY4NzA5MTEmYSti
+CmE9NTM2ODcwOTExJmErKCg1MjQyODcmYSk8PDEwKQpyZXR1cm4gYV5hPj4+Nn0sCnJFOmZ1bmN0aW9u
+KGEsYixjLGQpe3ZhciB0PVcuQzAoVy5DMChXLkMwKFcuQzAoMCxhKSxiKSxjKSxkKSxzPTUzNjg3MDkx
+MSZ0KygoNjcxMDg4NjMmdCk8PDMpCnNePXM+Pj4xMQpyZXR1cm4gNTM2ODcwOTExJnMrKCgxNjM4MyZz
+KTw8MTUpfSwKVE46ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9YS5jbGFzc0xpc3QKZm9yKHQ9Yi5sZW5n
+dGgscz0wO3M8Yi5sZW5ndGg7Yi5sZW5ndGg9PT10fHwoMCxILmxrKShiKSwrK3Mpci5hZGQoYltzXSl9
+LApKRTpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciB0PVcuYUYobmV3IFcudk4oYyksdS5CKQppZih0IT1u
+dWxsJiYhMClKLmRaKGEsYix0LCExKQpyZXR1cm4gbmV3IFcueEMoYSxiLHQsITEsZS5DKCJ4QzwwPiIp
+KX0sClR3OmZ1bmN0aW9uKGEpe3ZhciB0PVcuSjYoKSxzPXdpbmRvdy5sb2NhdGlvbgp0PW5ldyBXLkpR
+KG5ldyBXLm1rKHQscykpCnQuQ1koYSkKcmV0dXJuIHR9LAp5VzpmdW5jdGlvbihhLGIsYyxkKXt1Lmgu
+YShhKQpILmgoYikKSC5oKGMpCnUuY3IuYShkKQpyZXR1cm4hMH0sClFXOmZ1bmN0aW9uKGEsYixjLGQp
+e3ZhciB0LHMscgp1LmguYShhKQpILmgoYikKSC5oKGMpCnQ9dS5jci5hKGQpLmEKcz10LmEKcy5ocmVm
+PWMKcj1zLmhvc3RuYW1lCnQ9dC5iCmlmKCEocj09PXQuaG9zdG5hbWUmJnMucG9ydD09PXQucG9ydCYm
+cy5wcm90b2NvbD09PXQucHJvdG9jb2wpKWlmKHI9PT0iIilpZihzLnBvcnQ9PT0iIil7dD1zLnByb3Rv
+Y29sCnQ9dD09PSI6Inx8dD09PSIifWVsc2UgdD0hMQplbHNlIHQ9ITEKZWxzZSB0PSEwCnJldHVybiB0
+fSwKQmw6ZnVuY3Rpb24oKXt2YXIgdD11Lk4scz1QLnRNKEMuUXgsdCkscj11LmQwLmEobmV3IFcuSUEo
+KSkscT1ILlZNKFsiVEVNUExBVEUiXSx1LnMpCnQ9bmV3IFcuY3QocyxQLkxzKHQpLFAuTHModCksUC5M
+cyh0KSxudWxsKQp0LkNZKG51bGwsbmV3IEgubEooQy5ReCxyLHUuZmopLHEsbnVsbCkKcmV0dXJuIHR9
+LApQdjpmdW5jdGlvbihhKXtpZihhPT1udWxsKXJldHVybiBudWxsCnJldHVybiBXLlAxKGEpfSwKcWM6
+ZnVuY3Rpb24oYSl7dmFyIHQKaWYoYT09bnVsbClyZXR1cm4gbnVsbAppZigicG9zdE1lc3NhZ2UiIGlu
+IGEpe3Q9Vy5QMShhKQppZih1LmFTLmIodCkpcmV0dXJuIHQKcmV0dXJuIG51bGx9ZWxzZSByZXR1cm4g
+dS5jaC5hKGEpfSwKUDE6ZnVuY3Rpb24oYSl7aWYoYT09PXdpbmRvdylyZXR1cm4gdS5jaS5hKGEpCmVs
+c2UgcmV0dXJuIG5ldyBXLmRXKGEpfSwKSEg6ZnVuY3Rpb24oYSl7aWYoYT09PXdpbmRvdy5sb2NhdGlv
+bilyZXR1cm4gYQplbHNlIHJldHVybiBuZXcgVy5GYigpfSwKYUY6ZnVuY3Rpb24oYSxiKXt2YXIgdD0k
+LlgzCmlmKHQ9PT1DLk5VKXJldHVybiBhCnJldHVybiB0LlB5KGEsYil9LApxRTpmdW5jdGlvbiBxRSgp
+e30sCkdoOmZ1bmN0aW9uIEdoKCl7fSwKZlk6ZnVuY3Rpb24gZlkoKXt9LApuQjpmdW5jdGlvbiBuQigp
+e30sCkF6OmZ1bmN0aW9uIEF6KCl7fSwKUVA6ZnVuY3Rpb24gUVAoKXt9LApueDpmdW5jdGlvbiBueCgp
+e30sCm9KOmZ1bmN0aW9uIG9KKCl7fSwKaWQ6ZnVuY3Rpb24gaWQoKXt9LApRRjpmdW5jdGlvbiBRRigp
+e30sCk5oOmZ1bmN0aW9uIE5oKCl7fSwKYWU6ZnVuY3Rpb24gYWUoKXt9LApJQjpmdW5jdGlvbiBJQigp
+e30sCm43OmZ1bmN0aW9uIG43KCl7fSwKd3o6ZnVuY3Rpb24gd3ooYSxiKXt0aGlzLmE9YQp0aGlzLiR0
+aT1ifSwKY3Y6ZnVuY3Rpb24gY3YoKXt9LApDdjpmdW5jdGlvbiBDdigpe30sCmVhOmZ1bmN0aW9uIGVh
+KCl7fSwKRDA6ZnVuY3Rpb24gRDAoKXt9LApUNTpmdW5jdGlvbiBUNSgpe30sCmg0OmZ1bmN0aW9uIGg0
+KCl7fSwKYnI6ZnVuY3Rpb24gYnIoKXt9LApWYjpmdW5jdGlvbiBWYigpe30sCmZKOmZ1bmN0aW9uIGZK
+KCl7fSwKYlU6ZnVuY3Rpb24gYlUoYSl7dGhpcy5hPWF9LApoSDpmdW5jdGlvbiBoSChhLGIpe3RoaXMu
+YT1hCnRoaXMuYj1ifSwKd2E6ZnVuY3Rpb24gd2EoKXt9LApTZzpmdW5jdGlvbiBTZygpe30sCnU4OmZ1
+bmN0aW9uIHU4KCl7fSwKT0s6ZnVuY3Rpb24gT0soKXt9LAplNzpmdW5jdGlvbiBlNyhhKXt0aGlzLmE9
+YX0sCnVIOmZ1bmN0aW9uIHVIKCl7fSwKQkg6ZnVuY3Rpb24gQkgoKXt9LApTTjpmdW5jdGlvbiBTTigp
+e30sCmV3OmZ1bmN0aW9uIGV3KCl7fSwKbHA6ZnVuY3Rpb24gbHAoKXt9LApUYjpmdW5jdGlvbiBUYigp
+e30sCkl2OmZ1bmN0aW9uIEl2KCl7fSwKV1A6ZnVuY3Rpb24gV1AoKXt9LAp5WTpmdW5jdGlvbiB5WSgp
+e30sCnc2OmZ1bmN0aW9uIHc2KCl7fSwKSzU6ZnVuY3Rpb24gSzUoKXt9LApDbTpmdW5jdGlvbiBDbSgp
+e30sCkNROmZ1bmN0aW9uIENRKCl7fSwKdzQ6ZnVuY3Rpb24gdzQoKXt9LApyaDpmdW5jdGlvbiByaCgp
+e30sCmNmOmZ1bmN0aW9uIGNmKCl7fSwKaTc6ZnVuY3Rpb24gaTcoYSl7dGhpcy5hPWF9LApTeTpmdW5j
+dGlvbiBTeShhKXt0aGlzLmE9YX0sCktTOmZ1bmN0aW9uIEtTKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9
+LApBMzpmdW5jdGlvbiBBMyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKSTQ6ZnVuY3Rpb24gSTQoYSl7
+dGhpcy5hPWF9LApGazpmdW5jdGlvbiBGayhhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApSTzpmdW5j
+dGlvbiBSTyhhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uJHRpPWR9LApldTpm
+dW5jdGlvbiBldShhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uJHRpPWR9LAp4
+QzpmdW5jdGlvbiB4QyhhLGIsYyxkLGUpe3ZhciBfPXRoaXMKXy5iPWEKXy5jPWIKXy5kPWMKXy5lPWQK
+Xy4kdGk9ZX0sCnZOOmZ1bmN0aW9uIHZOKGEpe3RoaXMuYT1hfSwKSlE6ZnVuY3Rpb24gSlEoYSl7dGhp
+cy5hPWF9LApHbTpmdW5jdGlvbiBHbSgpe30sCnZEOmZ1bmN0aW9uIHZEKGEpe3RoaXMuYT1hfSwKVXY6
+ZnVuY3Rpb24gVXYoYSl7dGhpcy5hPWF9LApFZzpmdW5jdGlvbiBFZyhhLGIsYyl7dGhpcy5hPWEKdGhp
+cy5iPWIKdGhpcy5jPWN9LAptNjpmdW5jdGlvbiBtNigpe30sCkVvOmZ1bmN0aW9uIEVvKCl7fSwKV2s6
+ZnVuY3Rpb24gV2soKXt9LApjdDpmdW5jdGlvbiBjdChhLGIsYyxkLGUpe3ZhciBfPXRoaXMKXy5lPWEK
+Xy5hPWIKXy5iPWMKXy5jPWQKXy5kPWV9LApJQTpmdW5jdGlvbiBJQSgpe30sCk93OmZ1bmN0aW9uIE93
+KCl7fSwKVzk6ZnVuY3Rpb24gVzkoYSxiLGMpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPS0xCl8u
+ZD1udWxsCl8uJHRpPWN9LApkVzpmdW5jdGlvbiBkVyhhKXt0aGlzLmE9YX0sCkZiOmZ1bmN0aW9uIEZi
+KCl7fSwKa0Y6ZnVuY3Rpb24ga0YoKXt9LAptazpmdW5jdGlvbiBtayhhLGIpe3RoaXMuYT1hCnRoaXMu
+Yj1ifSwKS286ZnVuY3Rpb24gS28oYSl7dGhpcy5hPWEKdGhpcy5iPSExfSwKZm06ZnVuY3Rpb24gZm0o
+YSl7dGhpcy5hPWF9LApMZTpmdW5jdGlvbiBMZSgpe30sCks3OmZ1bmN0aW9uIEs3KCl7fSwKckI6ZnVu
+Y3Rpb24gckIoKXt9LApYVzpmdW5jdGlvbiBYVygpe30sCm9hOmZ1bmN0aW9uIG9hKCl7fX0sVT17Cmpm
+OmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxCmlmKGE9PW51bGwpdD1udWxsCmVsc2V7dD1ILlZNKFtdLHUu
+ZDcpCmZvcihzPUouSVQodS5ULmEoYSkpO3MuRigpOyl7cj1zLmdsKCkKcT1KLlU2KHIpCkMuTm0uaSh0
+LG5ldyBVLlNlKEguaChxLnEociwiZGVzY3JpcHRpb24iKSksSC5oKHEucShyLCJocmVmIikpKSl9fXJl
+dHVybiB0fSwKTmQ6ZnVuY3Rpb24oYSl7dmFyIHQscwppZihhPT1udWxsKXQ9bnVsbAplbHNle3Q9SC5W
+TShbXSx1LmFBKQpmb3Iocz1KLklUKHUuVC5hKGEpKTtzLkYoKTspQy5ObS5pKHQsVS5OZihzLmdsKCkp
+KX1yZXR1cm4gdH0sCk5mOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAsbz0iZGVzY3JpcHRpb24iLG49
+Si5VNihhKSxtPUguaChuLnEoYSxvKSksbD1ILlZNKFtdLHUuYUopCmZvcihuPUouSVQodS5ULmEobi5x
+KGEsImVudHJpZXMiKSkpO24uRigpOyl7dD1uLmdsKCkKcz1KLlU2KHQpCnI9SC5oKHMucSh0LG8pKQpx
+PUguaChzLnEodCwiZnVuY3Rpb24iKSkKcz1zLnEodCwibGluayIpCmlmKHM9PW51bGwpcz1udWxsCmVs
+c2V7cD1KLlU2KHMpCnM9bmV3IFUuTWwoSC5oKHAucShzLCJocmVmIikpLEgudVAocC5xKHMsImxpbmUi
+KSksSC5oKHAucShzLCJwYXRoIikpKX1DLk5tLmkobCxuZXcgVS53YihyLHEscykpfXJldHVybiBuZXcg
+VS55RChtLGwpfSwKZDI6ZnVuY3Rpb24gZDIoYSxiLGMsZCxlKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1i
+Cl8uYz1jCl8uZD1kCl8uZT1lfSwKU2U6ZnVuY3Rpb24gU2UoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0s
+Ck1sOmZ1bmN0aW9uIE1sKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCnlEOmZ1bmN0
+aW9uIHlEKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAp3YjpmdW5jdGlvbiB3YihhLGIsYyl7dGhpcy5h
+PWEKdGhpcy5iPWIKdGhpcy5jPWN9fSxCPXsKWWY6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG4s
+bSxsPUguaChhLnEoMCwicmVnaW9ucyIpKSxrPUguaChhLnEoMCwibmF2aWdhdGlvbkNvbnRlbnQiKSks
+aj1ILmgoYS5xKDAsInNvdXJjZUNvZGUiKSksaT1QLkZsKHUuWCx1LmRfKQpmb3IodD11LmEuYShhLnEo
+MCwiZWRpdHMiKSksdD10LmdQdSh0KSx0PXQuZ2t6KHQpLHM9dS5ULHI9dS5oNDt0LkYoKTspe3E9dC5n
+bCgpCnA9cS5hCm89SC5WTShbXSxyKQpmb3IocT1KLklUKHMuYShxLmIpKTtxLkYoKTspe249cS5nbCgp
+Cm09Si5VNihuKQpDLk5tLmkobyxuZXcgQi5qOChILnVQKG0ucShuLCJsaW5lIikpLEguaChtLnEobiwi
+ZXhwbGFuYXRpb24iKSksSC51UChtLnEobiwib2Zmc2V0IikpKSl9aS5ZKDAscCxvKX1yZXR1cm4gbmV3
+IEIucXAobCxrLGosaSl9LApqODpmdW5jdGlvbiBqOChhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhp
+cy5jPWN9LApxcDpmdW5jdGlvbiBxcChhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1j
+Cl8uZD1kfSwKZnY6ZnVuY3Rpb24gZnYoKXt9LApPUzpmdW5jdGlvbihhKXt2YXIgdAppZighKGE+PTY1
+JiZhPD05MCkpdD1hPj05NyYmYTw9MTIyCmVsc2UgdD0hMApyZXR1cm4gdH0sCll1OmZ1bmN0aW9uKGEs
+Yil7dmFyIHQ9YS5sZW5ndGgscz1iKzIKaWYodDxzKXJldHVybiExCmlmKCFCLk9TKEMueEIubShhLGIp
+KSlyZXR1cm4hMQppZihDLnhCLm0oYSxiKzEpIT09NTgpcmV0dXJuITEKaWYodD09PXMpcmV0dXJuITAK
+cmV0dXJuIEMueEIubShhLHMpPT09NDd9fSxUPXttUTpmdW5jdGlvbiBtUSgpe319LEw9ewpJcTpmdW5j
+dGlvbigpe0MuQlouQihkb2N1bWVudCwiRE9NQ29udGVudExvYWRlZCIsbmV3IEwuZSgpKQpDLm9sLkIo
+d2luZG93LCJwb3BzdGF0ZSIsbmV3IEwuTCgpKX0sCmt6OmZ1bmN0aW9uKGEpe3ZhciB0LHM9dS5nLmEo
+YS5wYXJlbnROb2RlKS5xdWVyeVNlbGVjdG9yKCI6c2NvcGUgPiB1bCIpLHI9cy5zdHlsZSxxPSIiK0Mu
+Q0QuelEocy5vZmZzZXRIZWlnaHQpKjIrInB4IgpyLm1heEhlaWdodD1xCnI9Si5xRihhKQpxPXIuJHRp
+CnQ9cS5DKCJ+KDEpPyIpLmEobmV3IEwuV3gocyxhKSkKdS5aLmEobnVsbCkKVy5KRShyLmEsci5iLHQs
+ITEscS5jKX0sCnlYOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvLG49InF1ZXJ5U2VsZWN0b3JB
+bGwiLG09ZG9jdW1lbnQucXVlcnlTZWxlY3RvcihhKSxsPXUuZwptLnRvU3RyaW5nCnQ9dS5oCkguRGgo
+bCx0LCJUIixuKQpzPXUuUgpyPW5ldyBXLnd6KG0ucXVlcnlTZWxlY3RvckFsbCgiLm5hdi1saW5rIiks
+cykKci5LKHIsbmV3IEwuQU8oYikpCkguRGgobCx0LCJUIixuKQpxPW5ldyBXLnd6KG0ucXVlcnlTZWxl
+Y3RvckFsbCgiLnJlZ2lvbiIpLHMpCmlmKHEuZ0EocSkhPT0wKXtwPW0ucXVlcnlTZWxlY3RvcigidGFi
+bGVbZGF0YS1wYXRoXSIpCnAudG9TdHJpbmcKcS5LKHEsbmV3IEwuSG8ocC5nZXRBdHRyaWJ1dGUoImRh
+dGEtIituZXcgVy5TeShuZXcgVy5pNyhwKSkuTygicGF0aCIpKSkpfUguRGgobCx0LCJUIixuKQpvPW5l
+dyBXLnd6KG0ucXVlcnlTZWxlY3RvckFsbCgiLmFkZC1oaW50LWxpbmsiKSxzKQpvLksobyxuZXcgTC5J
+QygpKX0sClE2OmZ1bmN0aW9uKGEsYil7dmFyIHQ9dS5YCnJldHVybiBXLnFEKEwuUTQoYSxiKSxQLkVG
+KFsiQ29udGVudC1UeXBlIiwiYXBwbGljYXRpb24vanNvbjsgY2hhcnNldD1VVEYtOCJdLHQsdCkpfSwK
+dHk6ZnVuY3Rpb24oYSl7dmFyIHQ9MCxzPVAuRlgodS5hKSxyLHEscCxvLG4sbSxsLGsKdmFyICRhc3lu
+YyR0eT1QLmx6KGZ1bmN0aW9uKGIsYyl7aWYoYj09PTEpcmV0dXJuIFAuZjMoYyxzKQp3aGlsZSh0cnVl
+KXN3aXRjaCh0KXtjYXNlIDA6bj1uZXcgUC52cygkLlgzLHUuZ1YpCm09bmV3IFAuWmYobix1LmJDKQps
+PW5ldyBYTUxIdHRwUmVxdWVzdCgpCms9dS5YCkMuRHQuZW8obCwiUE9TVCIsTC5RNChhLFAuRmwoayxr
+KSksITApCmwuc2V0UmVxdWVzdEhlYWRlcigiQ29udGVudC1UeXBlIiwiYXBwbGljYXRpb24vanNvbjsg
+Y2hhcnNldD1VVEYtOCIpCms9dS51CnE9ay5hKG5ldyBMLkwxKG0sbCkpCnUuWi5hKG51bGwpCnA9dS5F
+ClcuSkUobCwibG9hZCIscSwhMSxwKQpXLkpFKGwsImVycm9yIixrLmEobS5nWUooKSksITEscCkKbC5z
+ZW5kKCkKdD0zCnJldHVybiBQLmpRKG4sJGFzeW5jJHR5KQpjYXNlIDM6bz1DLkN0LnBXKDAsbC5yZXNw
+b25zZVRleHQsbnVsbCkKaWYobC5zdGF0dXM9PT0yMDApe3I9dS5hLmEobykKdD0xCmJyZWFrfWVsc2Ug
+dGhyb3cgSC5iKG8pCmNhc2UgMTpyZXR1cm4gUC55QyhyLHMpfX0pCnJldHVybiBQLkRJKCRhc3luYyR0
+eSxzKX0sCmFLOmZ1bmN0aW9uKGEpe3ZhciB0PVAuaEsoYSkuZ2hZKCkucSgwLCJsaW5lIikKcmV0dXJu
+IHQ9PW51bGw/bnVsbDpILkhwKHQsbnVsbCl9LApHNjpmdW5jdGlvbihhKXt2YXIgdD1QLmhLKGEpLmdo
+WSgpLnEoMCwib2Zmc2V0IikKcmV0dXJuIHQ9PW51bGw/bnVsbDpILkhwKHQsbnVsbCl9LAppNjpmdW5j
+dGlvbihhKXtyZXR1cm4gTC5uVyh1Lk8uYShhKSl9LApuVzpmdW5jdGlvbihhKXt2YXIgdD0wLHM9UC5G
+WCh1LnopLHI9MSxxLHA9W10sbyxuLG0sbCxrCnZhciAkYXN5bmMkaTY9UC5seihmdW5jdGlvbihiLGMp
+e2lmKGI9PT0xKXtxPWMKdD1yfXdoaWxlKHRydWUpc3dpdGNoKHQpe2Nhc2UgMDpsPXUuZy5hKFcucWMo
+YS5jdXJyZW50VGFyZ2V0KSkuZ2V0QXR0cmlidXRlKCJocmVmIikKYS5wcmV2ZW50RGVmYXVsdCgpCnI9
+Mwp0PTYKcmV0dXJuIFAualEoTC50eShsKSwkYXN5bmMkaTYpCmNhc2UgNjp1LmJaLmEoSi5HcihXLlB2
+KGRvY3VtZW50LmRlZmF1bHRWaWV3KSkpLnJlbG9hZCgpCnI9MQp0PTUKYnJlYWsKY2FzZSAzOnI9Mgpr
+PXEKbz1ILlJ1KGspCm49SC50cyhrKQpMLkMyKCJDb3VsZCBub3QgYWRkL3JlbW92ZSBoaW50IixvLG4p
+CnQ9NQpicmVhawpjYXNlIDI6dD0xCmJyZWFrCmNhc2UgNTpyZXR1cm4gUC55QyhudWxsLHMpCmNhc2Ug
+MTpyZXR1cm4gUC5mMyhxLHMpfX0pCnJldHVybiBQLkRJKCRhc3luYyRpNixzKX0sCkMyOmZ1bmN0aW9u
+KGEsYixjKXt2YXIgdCxzLHI9ImV4Y2VwdGlvbiIscT0ic3RhY2tUcmFjZSIscD11LmEuYihiKSYmSi5S
+TShiLnEoMCwic3VjY2VzcyIpLCExKSYmYi54NChyKSYmYi54NChxKSxvPUouaWEoYikKaWYocCl7dD1I
+Lmgoby5xKGIscikpCmM9by5xKGIscSl9ZWxzZSB0PW8udyhiKQpzPWRvY3VtZW50LnF1ZXJ5U2VsZWN0
+b3IoIi5wb3B1cC1wYW5lIikKcy5xdWVyeVNlbGVjdG9yKCJoMiIpLmlubmVyVGV4dD1hCnMucXVlcnlT
+ZWxlY3RvcigicCIpLmlubmVyVGV4dD10CnMucXVlcnlTZWxlY3RvcigicHJlIikuaW5uZXJUZXh0PUou
+aihjKQpwPXUuWAp1LmRkLmEocy5xdWVyeVNlbGVjdG9yKCJhLmJvdHRvbSIpKS5ocmVmPVAuWGQoImh0
+dHBzIiwiZ2l0aHViLmNvbSIsImRhcnQtbGFuZy9zZGsvaXNzdWVzL25ldyIsUC5FRihbInRpdGxlIiwi
+SXNzdWUgd2l0aCBOTkJEIG1pZ3JhdGlvbiB0b29sOiAiK2EsImxhYmVscyIsImFyZWEtYW5hbHl6ZXIs
+YW5hbHl6ZXItbm5iZC1taWdyYXRpb24sdHlwZS1idWciLCJib2R5IixhKyJcblxuRXJyb3I6ICIrSC5F
+aih0KSsiXG5cblBsZWFzZSBmaWxsIGluIHRoZSBmb2xsb3dpbmc6XG5cbioqTmFtZSBvZiBwYWNrYWdl
+IGJlaW5nIG1pZ3JhdGVkIChpZiBwdWJsaWMpKio6XG4qKldoYXQgSSB3YXMgZG9pbmcgd2hlbiB0aGlz
+IGlzc3VlIG9jY3VycmVkKio6XG4qKklzIGl0IHBvc3NpYmxlIHRvIHdvcmsgYXJvdW5kIHRoaXMgaXNz
+dWUqKjpcbioqSGFzIHRoaXMgaXNzdWUgaGFwcGVuZWQgYmVmb3JlLCBhbmQgaWYgc28sIGhvdyBvZnRl
+bioqOlxuKipEYXJ0IFNESyB2ZXJzaW9uKio6ICh2aXNpYmxlIGluIGxvd2VyIGxlZnQgb2YgbWlncmF0
+aW9uIHByZXZpZXcpXG4qKkFkZGl0aW9uYWwgZGV0YWlscyoqOlxuXG5UaGFua3MgZm9yIGZpbGluZyFc
+blxuU3RhY2t0cmFjZTogX2F1dG8gcG9wdWxhdGVkIGJ5IG1pZ3JhdGlvbiBwcmV2aWV3IHRvb2wuX1xu
+XG5gYGBcbiIrSC5FaihjKSsiXG5gYGBcbiJdLHAscCkpLmduRCgpCnA9cy5zdHlsZQpwLmRpc3BsYXk9
+ImluaXRpYWwiCkwucUooYSsiOiAiK0guRWooYiksYyl9LAp0MjpmdW5jdGlvbihhLGIsYyl7dmFyIHQs
+cyxyLHEscCxvLG49e30sbT11LmcuYShXLnFjKGEuY3VycmVudFRhcmdldCkpCmEucHJldmVudERlZmF1
+bHQoKQp0PW4uYT1tLmdldEF0dHJpYnV0ZSgiaHJlZiIpCmlmKEouemwodCwiPyIpKXtzPUMueEIuTmoo
+dCwwLEMueEIuT1kodCwiPyIpKQpuLmE9cwpyPXN9ZWxzZSByPXQKaWYoYyE9bnVsbCl7cT0kLm5VKCkK
+cj1uLmE9cS5vNShELm5yKHEudE0oYykscikpfXA9TC5HNih0KQpvPUwuYUsodCkKaWYocCE9bnVsbClM
+LmFmKHIscCxvLGIsbmV3IEwublQobixwLG8pKQplbHNlIEwuYWYocixudWxsLG51bGwsYixuZXcgTC5O
+WShuKSl9LAp2VTpmdW5jdGlvbigpe3ZhciB0PWRvY3VtZW50CkguRGgodS5nLHUuaCwiVCIsInF1ZXJ5
+U2VsZWN0b3JBbGwiKQp0PW5ldyBXLnd6KHQucXVlcnlTZWxlY3RvckFsbCgiLmNvZGUiKSx1LlIpCnQu
+Syh0LG5ldyBMLmVYKCkpfSwKaFg6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PXUuWApMLlE2KGEsUC5FRihb
+InJlZ2lvbiIsInJlZ2lvbiIsIm9mZnNldCIsSC5FaihiKV0sdCx0KSkuVzcobmV3IEwuRFQoYSxiLGMp
+LHUuUCkuT0EobmV3IEwuZUgoYSkpfSwKRzc6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgdAppZighSi5w
+NChhLCIuZGFydCIpKXtMLkJFKGEsbmV3IEIucXAoIiIsIiIsIiIsQy5DTSksZCkKTC5CWChhLG51bGwp
+CmlmKGUhPW51bGwpZS4kMCgpCnJldHVybn10PXUuWApMLlE2KGEsUC5FRihbImlubGluZSIsInRydWUi
+XSx0LHQpKS5XNyhuZXcgTC55dShhLGQsYixjLGUpLHUuUCkuT0EobmV3IEwuekQoYSkpfSwKR2U6ZnVu
+Y3Rpb24oKXt2YXIgdD0iL19wcmV2aWV3L25hdmlnYXRpb25UcmVlLmpzb24iCkwuUTYodCxDLldPKS5X
+NyhuZXcgTC5UVygpLHUuUCkuT0EobmV3IEwueHIodCkpfSwKcUo6ZnVuY3Rpb24oYSxiKXt2YXIgdAp3
+aW5kb3cKaWYodHlwZW9mIGNvbnNvbGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5jb25zb2xlLmVycm9yKGEp
+CndpbmRvdwp0PUguRWooYikKaWYodHlwZW9mIGNvbnNvbGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5jb25z
+b2xlLmVycm9yKHQpfSwKcU86ZnVuY3Rpb24oYSl7dmFyIHQ9YS5nZXRCb3VuZGluZ0NsaWVudFJlY3Qo
+KSxzPUMuQ0QuelEoJC5maSgpLm9mZnNldEhlaWdodCkscj13aW5kb3cuaW5uZXJIZWlnaHQscT1DLkNE
+LnpRKCQuRFcoKS5vZmZzZXRIZWlnaHQpCmlmKHQuYm90dG9tPnItKHErMTQpKUouZGgoYSkKZWxzZSBp
+Zih0LnRvcDxzKzE0KUouZGgoYSl9LApmRzpmdW5jdGlvbihhLGIpe3ZhciB0LHMscgppZihhIT1udWxs
+KXt0PWRvY3VtZW50CnM9dC5nZXRFbGVtZW50QnlJZCgibyIrSC5FaihhKSkKcj10LnF1ZXJ5U2VsZWN0
+b3IoIi5saW5lLSIrSC5FaihiKSkKaWYocyE9bnVsbCl7TC5xTyhzKQpKLmRSKHMpLmkoMCwidGFyZ2V0
+Iil9ZWxzZSBpZihyIT1udWxsKUwucU8oci5wYXJlbnRFbGVtZW50KQppZihyIT1udWxsKUouZFIodS5n
+LmEoci5wYXJlbnROb2RlKSkuaSgwLCJoaWdobGlnaHQiKX1lbHNlIEwucU8oJC5EOSgpKX0sCmFmOmZ1
+bmN0aW9uKGEsYixjLGQsZSl7dmFyIHQscyxyPUwuRzYod2luZG93LmxvY2F0aW9uLmhyZWYpLHE9TC5h
+Syh3aW5kb3cubG9jYXRpb24uaHJlZikKaWYociE9bnVsbCl7dD1kb2N1bWVudC5nZXRFbGVtZW50QnlJ
+ZCgibyIrSC5FaihyKSkKaWYodCE9bnVsbClKLmRSKHQpLlIoMCwidGFyZ2V0Iil9aWYocSE9bnVsbCl7
+cz1kb2N1bWVudC5xdWVyeVNlbGVjdG9yKCIubGluZS0iK0guRWoocSkpCmlmKHMhPW51bGwpSi5kUihz
+LnBhcmVudEVsZW1lbnQpLlIoMCwiaGlnaGxpZ2h0Iil9aWYoYT09PXdpbmRvdy5sb2NhdGlvbi5wYXRo
+bmFtZSl7TC5mRyhiLGMpCmUuJDAoKX1lbHNlIEwuRzcoYSxiLGMsZCxlKX0sClE0OmZ1bmN0aW9uKGEs
+Yil7dmFyIHQscyxyPVAuaEsoYSkscT11LlgKcT1QLkZsKHEscSkKZm9yKHQ9ci5naFkoKSx0PXQuZ1B1
+KHQpLHQ9dC5na3oodCk7dC5GKCk7KXtzPXQuZ2woKQpxLlkoMCxzLmEscy5iKX1mb3IodD1iLmdQdShi
+KSx0PXQuZ2t6KHQpO3QuRigpOyl7cz10LmdsKCkKcS5ZKDAscy5hLHMuYil9cS5ZKDAsImF1dGhUb2tl
+biIsJC5VRSgpKQpyZXR1cm4gci5ubSgwLHEpLmduRCgpfSwKVDE6ZnVuY3Rpb24oYSl7dmFyIHQscyxy
+LHEscCxvLG4sbSxsLGs9JC5oTCgpCkoubDUoaywiIikKaWYoYT09bnVsbCl7dD1kb2N1bWVudC5jcmVh
+dGVFbGVtZW50KCJwIikKQy5MdC5zYTQodCwiU2VlIGRldGFpbHMgYWJvdXQgYSBwcm9wb3NlZCBlZGl0
+LiIpCkMuTHQuc1AodCxILlZNKFsicGxhY2Vob2xkZXIiXSx1LmkpKQprLmFwcGVuZENoaWxkKHQpCkMu
+THQuRkYodCkKcmV0dXJufXM9YS5kCnI9JC5uVSgpCnE9ci50TShzKQpwPWEuYgpvPWRvY3VtZW50Cm49
+ci5IUChzLEouVDAoby5xdWVyeVNlbGVjdG9yKCIucm9vdCIpLnRleHRDb250ZW50KSkKbT1hLmMKbD1v
+LmNyZWF0ZUVsZW1lbnQoInAiKQprLmFwcGVuZENoaWxkKGwpCmwuYXBwZW5kQ2hpbGQoby5jcmVhdGVU
+ZXh0Tm9kZShILkVqKHApKyIgYXQgIitILkVqKG4pKyI6IitILkVqKG0pKyIuIikpCkouZGgobCkKTC5D
+QyhhLGsscSkKTC5GeihhLGspfSwKTEg6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxLHAsbyxuLG0s
+bCxrLGosaSxoLGc9JC55UCgpCkoubDUoZywiIikKaWYoYi5nQShiKT09PTApe3Q9ZG9jdW1lbnQKcz10
+LmNyZWF0ZUVsZW1lbnQoInAiKQpnLmFwcGVuZENoaWxkKHMpCnMuYXBwZW5kQ2hpbGQodC5jcmVhdGVU
+ZXh0Tm9kZSgiTm8gcHJvcG9zZWQgZWRpdHMiKSl9ZWxzZSBmb3IoZz1iLmdQdShiKSxnPWcuZ2t6KGcp
+LHQ9dS5HLHI9dC5DKCJ+KDEpPyIpLHE9dS5aLHQ9dC5jO2cuRigpOyl7cD1nLmdsKCkKbz1kb2N1bWVu
+dApzPW8uY3JlYXRlRWxlbWVudCgicCIpCm49JC55UCgpCm4uYXBwZW5kQ2hpbGQocykKcy5hcHBlbmRD
+aGlsZChvLmNyZWF0ZVRleHROb2RlKEguRWoocC5hKSsiOiIpKQptPW8uY3JlYXRlRWxlbWVudCgidWwi
+KQpuLmFwcGVuZENoaWxkKG0pCmZvcihwPUouSVQocC5iKTtwLkYoKTspe2w9cC5nbCgpCms9by5jcmVh
+dGVFbGVtZW50KCJsaSIpCm0uYXBwZW5kQ2hpbGQoaykKSi5kUihrKS5pKDAsImVkaXQiKQpqPW8uY3Jl
+YXRlRWxlbWVudCgiYSIpCmsuYXBwZW5kQ2hpbGQoaikKai5jbGFzc0xpc3QuYWRkKCJlZGl0LWxpbmsi
+KQppPWwuYwpuPUguRWooaSkKai5zZXRBdHRyaWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyhq
+KSkuTygib2Zmc2V0IiksbikKaD1sLmEKbj1ILkVqKGgpCmouc2V0QXR0cmlidXRlKCJkYXRhLSIrbmV3
+IFcuU3kobmV3IFcuaTcoaikpLk8oImxpbmUiKSxuKQpqLmFwcGVuZENoaWxkKG8uY3JlYXRlVGV4dE5v
+ZGUoImxpbmUgIitILkVqKGgpKSkKbj1yLmEobmV3IEwuRUUoaSxoLGEpKQpxLmEobnVsbCkKVy5KRShq
+LCJjbGljayIsbiwhMSx0KQprLmFwcGVuZENoaWxkKG8uY3JlYXRlVGV4dE5vZGUoIjogIitILkVqKGwu
+YikpKX19aWYoYylMLlQxKG51bGwpfSwKRnI6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscj13aW5kb3cu
+bG9jYXRpb24scT1QLmhLKChyJiZDLkV4KS5nRHIocikrSC5FaihhKSkKcj11LlgKcj1QLkZsKHIscikK
+aWYoYiE9bnVsbClyLlkoMCwib2Zmc2V0IixILkVqKGIpKQppZihjIT1udWxsKXIuWSgwLCJsaW5lIixI
+LkVqKGMpKQpyLlkoMCwiYXV0aFRva2VuIiwkLlVFKCkpCnE9cS5ubSgwLHIpCnI9d2luZG93Lmhpc3Rv
+cnkKdD11LnoKcz1xLmduRCgpCnIucHVzaFN0YXRlKG5ldyBQLkJmKFtdLFtdKS5QdihQLkZsKHQsdCkp
+LCIiLHMpfSwKRW46ZnVuY3Rpb24oYSl7dmFyIHQ9Si5iYihkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCIu
+cm9vdCIpLnRleHRDb250ZW50LCIvIikKaWYoQy54Qi5uKGEsdCkpcmV0dXJuIEMueEIuRyhhLHQubGVu
+Z3RoKQplbHNlIHJldHVybiBhfSwKQlg6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzPXt9CnMuYT1hCmE9TC5F
+bihhKQpzLmE9YQpKLmRyKCQuRDkoKSxhKQp0PWRvY3VtZW50CkguRGgodS5nLHUuaCwiVCIsInF1ZXJ5
+U2VsZWN0b3JBbGwiKQp0PW5ldyBXLnd6KHQucXVlcnlTZWxlY3RvckFsbCgiLm5hdi1wYW5lbCAubmF2
+LWxpbmsiKSx1LlIpCnQuSyh0LG5ldyBMLlZTKHMpKX0sCkJFOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD0i
+LnJlZ2lvbnMiLHM9ZG9jdW1lbnQscj1zLnF1ZXJ5U2VsZWN0b3IodCkscT1zLnF1ZXJ5U2VsZWN0b3Io
+Ii5jb2RlIikKSi50SChyLGIuYSwkLktHKCkpCkoudEgocSxiLmIsJC5LRygpKQpMLkxIKGEsYi5kLGMp
+CkwudlUoKQpMLnlYKCIuY29kZSIsITApCkwueVgodCwhMCl9LAp0WDpmdW5jdGlvbihhLGIpe3ZhciB0
+LHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGc9ZG9jdW1lbnQsZj1nLmNyZWF0ZUVsZW1lbnQoInVsIikK
+YS5hcHBlbmRDaGlsZChmKQpmb3IodD1iLmxlbmd0aCxzPXUuWixyPTA7cjxiLmxlbmd0aDtiLmxlbmd0
+aD09PXR8fCgwLEgubGspKGIpLCsrcil7cT1iW3JdCnA9Zy5jcmVhdGVFbGVtZW50KCJsaSIpCmYuYXBw
+ZW5kQ2hpbGQocCkKbz1KLllFKHApCmlmKHEuYT09PUMuWTIpe28uZ1AocCkuaSgwLCJkaXIiKQpuPWcu
+Y3JlYXRlRWxlbWVudCgic3BhbiIpCnAuYXBwZW5kQ2hpbGQobikKbz1KLllFKG4pCm8uZ1AobikuaSgw
+LCJhcnJvdyIpCm8uc2hmKG4sIiYjeDI1QkM7IikKbT1nLmNyZWF0ZUVsZW1lbnQoInNwYW4iKQpwLmFw
+cGVuZENoaWxkKG0pCkoubDUobSwiJiN4MUY0QzE7IikKcC5hcHBlbmRDaGlsZChnLmNyZWF0ZVRleHRO
+b2RlKHEuYikpCkwudFgocCxxLmMpCkwua3oobil9ZWxzZXtvLnNoZihwLCImI3gxRjRDNDsiKQpsPWcu
+Y3JlYXRlRWxlbWVudCgiYSIpCnAuYXBwZW5kQ2hpbGQobCkKbz1KLllFKGwpCm8uZ1AobCkuaSgwLCJu
+YXYtbGluayIpCmwuc2V0QXR0cmlidXRlKCJkYXRhLSIrbmV3IFcuU3kobmV3IFcuaTcobCkpLk8oIm5h
+bWUiKSxxLmQpCmwuc2V0QXR0cmlidXRlKCJocmVmIixxLmUpCmwuYXBwZW5kQ2hpbGQoZy5jcmVhdGVU
+ZXh0Tm9kZShxLmIpKQpvPW8uZ1ZsKGwpCms9by4kdGkKaj1rLkMoIn4oMSk/IikuYShuZXcgTC5URCgp
+KQpzLmEobnVsbCkKVy5KRShvLmEsby5iLGosITEsay5jKQppPXEuZgppZih0eXBlb2YgaSE9PSJudW1i
+ZXIiKXJldHVybiBpLm9zKCkKaWYoaT4wKXtoPWcuY3JlYXRlRWxlbWVudCgic3BhbiIpCnAuYXBwZW5k
+Q2hpbGQoaCkKSi5kUihoKS5pKDAsImVkaXQtY291bnQiKQpvPSIiK2krIiAiCmlmKGk9PT0xKWs9ImVk
+aXQiCmVsc2Ugaz0iZWRpdHMiCmguc2V0QXR0cmlidXRlKCJ0aXRsZSIsbytrKQpoLmFwcGVuZENoaWxk
+KGcuY3JlYXRlVGV4dE5vZGUoQy5qbi53KGkpKSl9fX19LApGejpmdW5jdGlvbihhLGIpe3ZhciB0LHMs
+cixxLHAsbyxuLG0sbCxrLGo9YS5hCmlmKGohPW51bGwpe3Q9ZG9jdW1lbnQKcz10LmNyZWF0ZUVsZW1l
+bnQoInAiKQpiLmFwcGVuZENoaWxkKHMpCmZvcihyPWoubGVuZ3RoLHE9dS5pLHA9dS5RLG89MDtvPGou
+bGVuZ3RoO2oubGVuZ3RoPT09cnx8KDAsSC5saykoaiksKytvKXtuPWpbb10KbT10LmNyZWF0ZUVsZW1l
+bnQoImEiKQpzLmFwcGVuZENoaWxkKG0pCm0uYXBwZW5kQ2hpbGQodC5jcmVhdGVUZXh0Tm9kZShuLmEp
+KQptLnNldEF0dHJpYnV0ZSgiaHJlZiIsbi5iKQpsPXAuYShILlZNKFsiYWRkLWhpbnQtbGluayIsImJl
+Zm9yZS1hcHBseSIsImJ1dHRvbiJdLHEpKQprPUouZFIobSkKay5WMSgwKQprLkZWKDAsbCl9fX0sCkND
+OmZ1bmN0aW9uKGEyLGEzLGE0KXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGksaCxnLGYsZSxkLGMs
+YixhLGEwLGExPW51bGwKZm9yKHQ9YTIuZSxzPXQubGVuZ3RoLHI9dS5pLHE9dS5RLHA9MDtwPHQubGVu
+Z3RoO3QubGVuZ3RoPT09c3x8KDAsSC5saykodCksKytwKXtvPXRbcF0Kbj1kb2N1bWVudAptPW4uY3Jl
+YXRlRWxlbWVudCgicCIpCmw9cS5hKEguVk0oWyJ0cmFjZSJdLHIpKQprPUouZFIobSkKay5WMSgwKQpr
+LkZWKDAsbCkKaj1hMy5hcHBlbmRDaGlsZChtKQptPW4uY3JlYXRlRWxlbWVudCgic3BhbiIpCmw9cS5h
+KEguVk0oWyJ0eXBlLWRlc2NyaXB0aW9uIl0scikpCms9Si5kUihtKQprLlYxKDApCmsuRlYoMCxsKQpt
+LmFwcGVuZENoaWxkKG4uY3JlYXRlVGV4dE5vZGUoby5hKSkKai5hcHBlbmRDaGlsZChtKQpqLmFwcGVu
+ZENoaWxkKG4uY3JlYXRlVGV4dE5vZGUoIjoiKSkKbT1uLmNyZWF0ZUVsZW1lbnQoInVsIikKbD1xLmEo
+SC5WTShbInRyYWNlIl0scikpCms9Si5kUihtKQprLlYxKDApCmsuRlYoMCxsKQppPWouYXBwZW5kQ2hp
+bGQobSkKZm9yKG09by5iLGw9bS5sZW5ndGgsaD0wO2g8bS5sZW5ndGg7bS5sZW5ndGg9PT1sfHwoMCxI
+LmxrKShtKSwrK2gpe2c9bVtoXQpmPW4uY3JlYXRlRWxlbWVudCgibGkiKQpKLmw1KGYsIiYjeDI3NEY7
+ICIpCmkuYXBwZW5kQ2hpbGQoZikKZT1uLmNyZWF0ZUVsZW1lbnQoInNwYW4iKQpkPXEuYShILlZNKFsi
+ZnVuY3Rpb24iXSxyKSkKaz1KLmRSKGUpCmsuVjEoMCkKay5GVigwLGQpCmQ9Zy5iCkwua0QoZSxkPT1u
+dWxsPyJ1bmtub3duIjpkKQpmLmFwcGVuZENoaWxkKGUpCmM9Zy5jCmlmKGMhPW51bGwpe2YuYXBwZW5k
+Q2hpbGQobi5jcmVhdGVUZXh0Tm9kZSgiICgiKSkKYj1jLmIKYT1uLmNyZWF0ZUVsZW1lbnQoImEiKQph
+LmFwcGVuZENoaWxkKG4uY3JlYXRlVGV4dE5vZGUoSC5FaihjLmMpKyI6IitILkVqKGIpKSkKYTA9Yy5h
+CmU9JC5uVSgpCmEuc2V0QXR0cmlidXRlKCJocmVmIixlLm81KGUucTcoMCxhNCxhMCxhMSxhMSxhMSxh
+MSxhMSxhMSkpKQphLmNsYXNzTGlzdC5hZGQoIm5hdi1saW5rIikKZi5hcHBlbmRDaGlsZChhKQpmLmFw
+cGVuZENoaWxkKG4uY3JlYXRlVGV4dE5vZGUoIikiKSl9Zi5hcHBlbmRDaGlsZChuLmNyZWF0ZVRleHRO
+b2RlKCI6ICIpKQplPWcuYQpMLmtEKGYsZT09bnVsbD8idW5rbm93biI6ZSl9fX0sCmtEOmZ1bmN0aW9u
+KGEsYil7dmFyIHQscyxyPUguVk0oYi5zcGxpdCgiLiIpLHUucykscT1DLk5tLmd0SChyKSxwPWRvY3Vt
+ZW50CmEuYXBwZW5kQ2hpbGQocC5jcmVhdGVUZXh0Tm9kZShxKSkKZm9yKHE9SC5xQyhyLDEsbnVsbCx1
+Lk4pLHE9bmV3IEguYTcocSxxLmdBKHEpLHEuJHRpLkMoImE3PGFMLkU+IikpLHQ9Si5ZRShhKTtxLkYo
+KTspe3M9cS5kCnQubnooYSwiYmVmb3JlZW5kIiwiJiM4MjAzOy4iLG51bGwsbnVsbCkKYS5hcHBlbmRD
+aGlsZChwLmNyZWF0ZVRleHROb2RlKHMpKX19LAplOmZ1bmN0aW9uIGUoKXt9LApWVzpmdW5jdGlvbiBW
+VyhhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApvWjpmdW5jdGlvbiBvWigpe30sCmpy
+OmZ1bmN0aW9uIGpyKCl7fSwKcWw6ZnVuY3Rpb24gcWwoKXt9LApIaTpmdW5jdGlvbiBIaSgpe30sCkJU
+OmZ1bmN0aW9uIEJUKCl7fSwKUFk6ZnVuY3Rpb24gUFkoKXt9LApMOmZ1bmN0aW9uIEwoKXt9LApXeDpm
+dW5jdGlvbiBXeChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKQU86ZnVuY3Rpb24gQU8oYSl7dGhpcy5h
+PWF9LApkTjpmdW5jdGlvbiBkTihhKXt0aGlzLmE9YX0sCkhvOmZ1bmN0aW9uIEhvKGEpe3RoaXMuYT1h
+fSwKeHo6ZnVuY3Rpb24geHooYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCklDOmZ1bmN0aW9uIElDKCl7
+fSwKTDE6ZnVuY3Rpb24gTDEoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCm5UOmZ1bmN0aW9uIG5UKGEs
+YixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCk5ZOmZ1bmN0aW9uIE5ZKGEpe3RoaXMuYT1h
+fSwKZVg6ZnVuY3Rpb24gZVgoKXt9LApEVDpmdW5jdGlvbiBEVChhLGIsYyl7dGhpcy5hPWEKdGhpcy5i
+PWIKdGhpcy5jPWN9LAplSDpmdW5jdGlvbiBlSChhKXt0aGlzLmE9YX0sCnl1OmZ1bmN0aW9uIHl1KGEs
+YixjLGQsZSl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZApfLmU9ZX0sCnpEOmZ1bmN0
+aW9uIHpEKGEpe3RoaXMuYT1hfSwKVFc6ZnVuY3Rpb24gVFcoKXt9LAp4cjpmdW5jdGlvbiB4cihhKXt0
+aGlzLmE9YX0sCkVFOmZ1bmN0aW9uIEVFKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30s
+ClFMOmZ1bmN0aW9uIFFMKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApWUzpmdW5jdGlvbiBWUyhhKXt0
+aGlzLmE9YX0sClREOmZ1bmN0aW9uIFREKCl7fSwKWEE6ZnVuY3Rpb24gWEEoKXt9LAptSzpmdW5jdGlv
+bihhKXt2YXIgdCxzLHIscSxwLG8sbj1ILlZNKFtdLHUuY1EpCmZvcih0PUouSVQodS5ULmEoYSkpO3Qu
+RigpOyl7cz10LmdsKCkKcj1KLlU2KHMpCnE9TC5wMihILmgoci5xKHMsInR5cGUiKSkpCnA9SC5oKHIu
+cShzLCJuYW1lIikpCm89ci5xKHMsInN1YnRyZWUiKQpvPW89PW51bGw/bnVsbDpMLm1LKG8pCkMuTm0u
+aShuLG5ldyBMLlpaKHEscCxvLEguaChyLnEocywicGF0aCIpKSxILmgoci5xKHMsImhyZWYiKSksSC51
+UChyLnEocywiZWRpdENvdW50IikpKSl9cmV0dXJuIG59LApwMjpmdW5jdGlvbihhKXtzd2l0Y2goYSl7
+Y2FzZSJkaXJlY3RvcnkiOnJldHVybiBDLlkyCmNhc2UiZmlsZSI6cmV0dXJuIEMucmYKZGVmYXVsdDp0
+aHJvdyBILmIoUC5QVigiVW5yZWNvZ25pemVkIG5hdmlnYXRpb24gdHJlZSBub2RlIHR5cGU6ICIrSC5F
+aihhKSkpfX0sClpaOmZ1bmN0aW9uIFpaKGEsYixjLGQsZSxmKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1i
+Cl8uYz1jCl8uZD1kCl8uZT1lCl8uZj1mfSwKTzk6ZnVuY3Rpb24gTzkoYSl7dGhpcy5iPWF9LApJVjpm
+dW5jdGlvbiBJVihhLGIsYyxkKXt2YXIgXz10aGlzCl8uZD1hCl8uZT1iCl8uZj1jCl8ucj1kfX0sTT17
+CllGOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvLG4KZm9yKHQ9Yi5sZW5ndGgscz0xO3M8dDsr
+K3Mpe2lmKGJbc109PW51bGx8fGJbcy0xXSE9bnVsbCljb250aW51ZQpmb3IoO3Q+PTE7dD1yKXtyPXQt
+MQppZihiW3JdIT1udWxsKWJyZWFrfXE9bmV3IFAuUm4oIiIpCnA9IiIrKGErIigiKQpxLmE9cApvPUgu
+cUMoYiwwLHQsSC50NihiKS5jKQpuPW8uJHRpCm49cCtuZXcgSC5sSihvLG4uQygicVUqKGFMLkUpIiku
+YShuZXcgTS5ObygpKSxuLkMoImxKPGFMLkUscVUqPiIpKS56VigwLCIsICIpCnEuYT1uCnEuYT1uKygi
+KTogcGFydCAiKyhzLTEpKyIgd2FzIG51bGwsIGJ1dCBwYXJ0ICIrcysiIHdhcyBub3QuIikKdGhyb3cg
+SC5iKFAueFkocS53KDApKSl9fSwKbEk6ZnVuY3Rpb24gbEkoYSl7dGhpcy5hPWF9LApNaTpmdW5jdGlv
+biBNaSgpe30sCnE3OmZ1bmN0aW9uIHE3KCl7fSwKTm86ZnVuY3Rpb24gTm8oKXt9fSxYPXsKQ0w6ZnVu
+Y3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG89Yi54WihhKQpiLmhLKGEpCmlmKG8hPW51bGwpYT1KLktW
+KGEsby5sZW5ndGgpCnQ9dS5pCnM9SC5WTShbXSx0KQpyPUguVk0oW10sdCkKdD1hLmxlbmd0aAppZih0
+IT09MCYmYi5yNChDLnhCLlcoYSwwKSkpe2lmKDA+PXQpcmV0dXJuIEguT0goYSwwKQpDLk5tLmkocixh
+WzBdKQpxPTF9ZWxzZXtDLk5tLmkociwiIikKcT0wfWZvcihwPXE7cDx0OysrcClpZihiLnI0KEMueEIu
+VyhhLHApKSl7Qy5ObS5pKHMsQy54Qi5OaihhLHEscCkpCkMuTm0uaShyLGFbcF0pCnE9cCsxfWlmKHE8
+dCl7Qy5ObS5pKHMsQy54Qi5HKGEscSkpCkMuTm0uaShyLCIiKX1yZXR1cm4gbmV3IFguV0QoYixvLHMs
+cil9LApXRDpmdW5jdGlvbiBXRChhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uZD1jCl8u
+ZT1kfSwKcVI6ZnVuY3Rpb24gcVIoYSl7dGhpcy5hPWF9LApJNzpmdW5jdGlvbihhKXtyZXR1cm4gbmV3
+IFguZHYoYSl9LApkdjpmdW5jdGlvbiBkdihhKXt0aGlzLmE9YX19LE89ewpSaDpmdW5jdGlvbigpe3Zh
+ciB0LHM9bnVsbAppZihQLnVvKCkuZ0ZpKCkhPT0iZmlsZSIpcmV0dXJuICQuRWIoKQp0PVAudW8oKQpp
+ZighQy54Qi5UYyh0LmdJaSh0KSwiLyIpKXJldHVybiAkLkViKCkKaWYoUC5LTChzLCJhL2IiLHMscyxz
+LHMscykudDQoKT09PSJhXFxiIilyZXR1cm4gJC5LaygpCnJldHVybiAkLmJEKCl9LAp6TDpmdW5jdGlv
+biB6TCgpe319LEU9e09GOmZ1bmN0aW9uIE9GKGEsYixjKXt0aGlzLmQ9YQp0aGlzLmU9Ygp0aGlzLmY9
+Y319LEY9e3J1OmZ1bmN0aW9uIHJ1KGEsYixjLGQpe3ZhciBfPXRoaXMKXy5kPWEKXy5lPWIKXy5mPWMK
+Xy5yPWR9fSxEPXsKUlg6ZnVuY3Rpb24oKXt2YXIgdCxzLHI9UC51bygpCmlmKHIuRE4oMCwkLkk2KSly
+ZXR1cm4gJC5GZgokLkk2PXIKaWYoJC5IaygpPT0kLkViKCkpcmV0dXJuICQuRmY9ci5aSSgiLiIpLnco
+MCkKZWxzZXt0PXIudDQoKQpzPXQubGVuZ3RoLTEKcmV0dXJuICQuRmY9cz09PTA/dDpDLnhCLk5qKHQs
+MCxzKX19LApucjpmdW5jdGlvbihhLGIpe3ZhciB0PW51bGwKcmV0dXJuICQublUoKS5xNygwLGEsYix0
+LHQsdCx0LHQsdCl9fQp2YXIgdz1bQyxILEosUCxXLFUsQixULEwsTSxYLE8sRSxGLERdCmh1bmtIZWxw
+ZXJzLnNldEZ1bmN0aW9uTmFtZXNJZk5lY2Vzc2FyeSh3KQp2YXIgJD17fQpILkZLLnByb3RvdHlwZT17
+fQpKLnZCLnByb3RvdHlwZT17CkROOmZ1bmN0aW9uKGEsYil7cmV0dXJuIGE9PT1ifSwKZ2lPOmZ1bmN0
+aW9uKGEpe3JldHVybiBILmVRKGEpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4iSW5zdGFuY2Ugb2YgJyIr
+SC5FaihILk0oYSkpKyInIn0sCmU3OmZ1bmN0aW9uKGEsYil7dS5vLmEoYikKdGhyb3cgSC5iKFAubHIo
+YSxiLmdXYSgpLGIuZ25kKCksYi5nVm0oKSkpfX0KSi55RS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEp
+e3JldHVybiBTdHJpbmcoYSl9LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJuIGE/NTE5MDE4OjIxODE1OX0s
+CiRpYTI6MX0KSi53ZS5wcm90b3R5cGU9ewpETjpmdW5jdGlvbihhLGIpe3JldHVybiBudWxsPT1ifSwK
+dzpmdW5jdGlvbihhKXtyZXR1cm4ibnVsbCJ9LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJuIDB9LAplNzpm
+dW5jdGlvbihhLGIpe3JldHVybiB0aGlzLlNqKGEsdS5vLmEoYikpfSwKJGljODoxfQpKLk1GLnByb3Rv
+dHlwZT17CmdpTzpmdW5jdGlvbihhKXtyZXR1cm4gMH0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFN0cmlu
+ZyhhKX0sCiRpdm06MX0KSi5pQy5wcm90b3R5cGU9e30KSi5rZC5wcm90b3R5cGU9e30KSi5jNS5wcm90
+b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciB0PWFbJC53KCldCmlmKHQ9PW51bGwpcmV0dXJuIHRoaXMu
+dChhKQpyZXR1cm4iSmF2YVNjcmlwdCBmdW5jdGlvbiBmb3IgIitILkVqKEouaih0KSl9LAokUzpmdW5j
+dGlvbigpe3JldHVybntmdW5jOjEsb3B0OlssLCwsLCwsLCwsLCwsLCwsXX19LAokaUVIOjF9CkouamQu
+cHJvdG90eXBlPXsKaTpmdW5jdGlvbihhLGIpe0gudDYoYSkuYy5hKGIpCmlmKCEhYS5maXhlZCRsZW5n
+dGgpSC52aChQLkw0KCJhZGQiKSkKYS5wdXNoKGIpfSwKVzQ6ZnVuY3Rpb24oYSxiKXt2YXIgdAppZigh
+IWEuZml4ZWQkbGVuZ3RoKUgudmgoUC5MNCgicmVtb3ZlQXQiKSkKdD1hLmxlbmd0aAppZihiPj10KXRo
+cm93IEguYihQLk83KGIsbnVsbCkpCnJldHVybiBhLnNwbGljZShiLDEpWzBdfSwKVUc6ZnVuY3Rpb24o
+YSxiLGMpe3ZhciB0LHMscgpILnQ2KGEpLkMoImNYPDE+IikuYShjKQppZighIWEuZml4ZWQkbGVuZ3Ro
+KUgudmgoUC5MNCgiaW5zZXJ0QWxsIikpCnQ9YS5sZW5ndGgKUC53QShiLDAsdCwiaW5kZXgiKQpzPWMu
+bGVuZ3RoCnRoaXMuc0EoYSx0K3MpCnI9YitzCnRoaXMuWVcoYSxyLGEubGVuZ3RoLGEsYikKdGhpcy52
+ZyhhLGIscixjKX0sCm12OmZ1bmN0aW9uKGEpe2lmKCEhYS5maXhlZCRsZW5ndGgpSC52aChQLkw0KCJy
+ZW1vdmVMYXN0IikpCmlmKGEubGVuZ3RoPT09MCl0aHJvdyBILmIoSC5IWShhLC0xKSkKcmV0dXJuIGEu
+cG9wKCl9LApGVjpmdW5jdGlvbihhLGIpe3ZhciB0CkgudDYoYSkuQygiY1g8MT4iKS5hKGIpCmlmKCEh
+YS5maXhlZCRsZW5ndGgpSC52aChQLkw0KCJhZGRBbGwiKSkKZm9yKHQ9Si5JVChiKTt0LkYoKTspYS5w
+dXNoKHQuZ2woKSl9LApFMjpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9SC50NihhKQpyZXR1cm4gbmV3IEgu
+bEooYSx0LktxKGMpLkMoIjEoMikiKS5hKGIpLHQuQygiQDwxPiIpLktxKGMpLkMoImxKPDEsMj4iKSl9
+LAp6VjpmdW5jdGlvbihhLGIpe3ZhciB0LHM9UC5POChhLmxlbmd0aCwiIiwhMSx1Lk4pCmZvcih0PTA7
+dDxhLmxlbmd0aDsrK3QpdGhpcy5ZKHMsdCxILkVqKGFbdF0pKQpyZXR1cm4gcy5qb2luKGIpfSwKTjA6
+ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyCmQuYShiKQpILnQ2KGEpLktxKGQpLkMoIjEoMSwyKSIp
+LmEoYykKdD1hLmxlbmd0aApmb3Iocz1iLHI9MDtyPHQ7KytyKXtzPWMuJDIocyxhW3JdKQppZihhLmxl
+bmd0aCE9PXQpdGhyb3cgSC5iKFAuYTQoYSkpfXJldHVybiBzfSwKRTpmdW5jdGlvbihhLGIpe2lmKGI8
+MHx8Yj49YS5sZW5ndGgpcmV0dXJuIEguT0goYSxiKQpyZXR1cm4gYVtiXX0sCmd0SDpmdW5jdGlvbihh
+KXtpZihhLmxlbmd0aD4wKXJldHVybiBhWzBdCnRocm93IEguYihILldwKCkpfSwKZ3JaOmZ1bmN0aW9u
+KGEpe3ZhciB0PWEubGVuZ3RoCmlmKHQ+MClyZXR1cm4gYVt0LTFdCnRocm93IEguYihILldwKCkpfSwK
+WVc6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgdCxzLHIscQpILnQ2KGEpLkMoImNYPDE+IikuYShkKQpp
+ZighIWEuaW1tdXRhYmxlJGxpc3QpSC52aChQLkw0KCJzZXRSYW5nZSIpKQpQLmpCKGIsYyxhLmxlbmd0
+aCkKdD1jLWIKaWYodD09PTApcmV0dXJuClAuazEoZSwic2tpcENvdW50IikKcz1kCnI9Si5VNihzKQpp
+ZihlK3Q+ci5nQShzKSl0aHJvdyBILmIoSC5hcigpKQppZihlPGIpZm9yKHE9dC0xO3E+PTA7LS1xKWFb
+YitxXT1yLnEocyxlK3EpCmVsc2UgZm9yKHE9MDtxPHQ7KytxKWFbYitxXT1yLnEocyxlK3EpfSwKdmc6
+ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJuIHRoaXMuWVcoYSxiLGMsZCwwKX0sClZyOmZ1bmN0aW9uKGEs
+Yil7dmFyIHQscwpILnQ2KGEpLkMoImEyKDEpIikuYShiKQp0PWEubGVuZ3RoCmZvcihzPTA7czx0Oysr
+cyl7aWYoSC5vVChiLiQxKGFbc10pKSlyZXR1cm4hMAppZihhLmxlbmd0aCE9PXQpdGhyb3cgSC5iKFAu
+YTQoYSkpfXJldHVybiExfSwKdGc6ZnVuY3Rpb24oYSxiKXt2YXIgdApmb3IodD0wO3Q8YS5sZW5ndGg7
+Kyt0KWlmKEouUk0oYVt0XSxiKSlyZXR1cm4hMApyZXR1cm4hMX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJu
+IFAuV0UoYSwiWyIsIl0iKX0sCmdrejpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEoubTEoYSxhLmxlbmd0
+aCxILnQ2KGEpLkMoIm0xPDE+IikpfSwKZ2lPOmZ1bmN0aW9uKGEpe3JldHVybiBILmVRKGEpfSwKZ0E6
+ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwKc0E6ZnVuY3Rpb24oYSxiKXtpZighIWEuZml4ZWQk
+bGVuZ3RoKUgudmgoUC5MNCgic2V0IGxlbmd0aCIpKQphLmxlbmd0aD1ifSwKcTpmdW5jdGlvbihhLGIp
+e0gudVAoYikKaWYoYj49YS5sZW5ndGh8fGI8MCl0aHJvdyBILmIoSC5IWShhLGIpKQpyZXR1cm4gYVti
+XX0sClk6ZnVuY3Rpb24oYSxiLGMpe0gudDYoYSkuYy5hKGMpCmlmKCEhYS5pbW11dGFibGUkbGlzdClI
+LnZoKFAuTDQoImluZGV4ZWQgc2V0IikpCmlmKGI+PWEubGVuZ3RofHxiPDApdGhyb3cgSC5iKEguSFko
+YSxiKSkKYVtiXT1jfSwKJGliUToxLAokaWNYOjEsCiRpek06MX0KSi5Qby5wcm90b3R5cGU9e30KSi5t
+MS5wcm90b3R5cGU9ewpnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmR9LApGOmZ1bmN0aW9uKCl7dmFy
+IHQscz10aGlzLHI9cy5hLHE9ci5sZW5ndGgKaWYocy5iIT09cSl0aHJvdyBILmIoSC5sayhyKSkKdD1z
+LmMKaWYodD49cSl7cy5zSChudWxsKQpyZXR1cm4hMX1zLnNIKHJbdF0pOysrcy5jCnJldHVybiEwfSwK
+c0g6ZnVuY3Rpb24oYSl7dGhpcy5kPXRoaXMuJHRpLkMoIjE/IikuYShhKX0sCiRpQW46MX0KSi5xSS5w
+cm90b3R5cGU9ewp6UTpmdW5jdGlvbihhKXtpZihhPjApe2lmKGEhPT0xLzApcmV0dXJuIE1hdGgucm91
+bmQoYSl9ZWxzZSBpZihhPi0xLzApcmV0dXJuIDAtTWF0aC5yb3VuZCgwLWEpCnRocm93IEguYihQLkw0
+KCIiK2ErIi5yb3VuZCgpIikpfSwKV1o6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscQppZihiPDJ8fGI+
+MzYpdGhyb3cgSC5iKFAuVEUoYiwyLDM2LCJyYWRpeCIsbnVsbCkpCnQ9YS50b1N0cmluZyhiKQppZihD
+LnhCLm0odCx0Lmxlbmd0aC0xKSE9PTQxKXJldHVybiB0CnM9L14oW1xkYS16XSspKD86XC4oW1xkYS16
+XSspKT9cKGVcKyhcZCspXCkkLy5leGVjKHQpCmlmKHM9PW51bGwpSC52aChQLkw0KCJVbmV4cGVjdGVk
+IHRvU3RyaW5nIHJlc3VsdDogIit0KSkKcj1zLmxlbmd0aAppZigxPj1yKXJldHVybiBILk9IKHMsMSkK
+dD1zWzFdCmlmKDM+PXIpcmV0dXJuIEguT0gocywzKQpxPStzWzNdCnI9c1syXQppZihyIT1udWxsKXt0
+Kz1yCnEtPXIubGVuZ3RofXJldHVybiB0K0MueEIuSXgoIjAiLHEpfSwKdzpmdW5jdGlvbihhKXtpZihh
+PT09MCYmMS9hPDApcmV0dXJuIi0wLjAiCmVsc2UgcmV0dXJuIiIrYX0sCmdpTzpmdW5jdGlvbihhKXt2
+YXIgdCxzLHIscSxwPWF8MAppZihhPT09cClyZXR1cm4gNTM2ODcwOTExJnAKdD1NYXRoLmFicyhhKQpz
+PU1hdGgubG9nKHQpLzAuNjkzMTQ3MTgwNTU5OTQ1M3wwCnI9TWF0aC5wb3coMixzKQpxPXQ8MT90L3I6
+ci90CnJldHVybiA1MzY4NzA5MTEmKChxKjkwMDcxOTkyNTQ3NDA5OTJ8MCkrKHEqMzU0MjI0MzE4MTE3
+NjUyMXwwKSkqNTk5MTk3K3MqMTI1OX0sCnpZOmZ1bmN0aW9uKGEsYil7dmFyIHQ9YSViCmlmKHQ9PT0w
+KXJldHVybiAwCmlmKHQ+MClyZXR1cm4gdAppZihiPDApcmV0dXJuIHQtYgplbHNlIHJldHVybiB0K2J9
+LAp3RzpmdW5jdGlvbihhLGIpe3ZhciB0CmlmKGE+MCl0PXRoaXMucDMoYSxiKQplbHNle3Q9Yj4zMT8z
+MTpiCnQ9YT4+dD4+PjB9cmV0dXJuIHR9LApiZjpmdW5jdGlvbihhLGIpe2lmKGI8MCl0aHJvdyBILmIo
+SC50TChiKSkKcmV0dXJuIHRoaXMucDMoYSxiKX0sCnAzOmZ1bmN0aW9uKGEsYil7cmV0dXJuIGI+MzE/
+MDphPj4+Yn0sCiRpQ1A6MSwKJGlsZjoxfQpKLnVyLnByb3RvdHlwZT17JGlJZjoxfQpKLlZBLnByb3Rv
+dHlwZT17fQpKLkRyLnByb3RvdHlwZT17Cm06ZnVuY3Rpb24oYSxiKXtpZihiPDApdGhyb3cgSC5iKEgu
+SFkoYSxiKSkKaWYoYj49YS5sZW5ndGgpSC52aChILkhZKGEsYikpCnJldHVybiBhLmNoYXJDb2RlQXQo
+Yil9LApXOmZ1bmN0aW9uKGEsYil7aWYoYj49YS5sZW5ndGgpdGhyb3cgSC5iKEguSFkoYSxiKSkKcmV0
+dXJuIGEuY2hhckNvZGVBdChiKX0sCmRkOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBILnVuKGIsYSww
+KX0sCmg6ZnVuY3Rpb24oYSxiKXtpZih0eXBlb2YgYiE9InN0cmluZyIpdGhyb3cgSC5iKFAuTDMoYixu
+dWxsLG51bGwpKQpyZXR1cm4gYStifSwKVGM6ZnVuY3Rpb24oYSxiKXt2YXIgdD1iLmxlbmd0aCxzPWEu
+bGVuZ3RoCmlmKHQ+cylyZXR1cm4hMQpyZXR1cm4gYj09PXRoaXMuRyhhLHMtdCl9LAppNzpmdW5jdGlv
+bihhLGIsYyxkKXt2YXIgdD1QLmpCKGIsYyxhLmxlbmd0aCkscz1hLnN1YnN0cmluZygwLGIpLHI9YS5z
+dWJzdHJpbmcodCkKcmV0dXJuIHMrZCtyfSwKUWk6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0CmlmKGM8MHx8
+Yz5hLmxlbmd0aCl0aHJvdyBILmIoUC5URShjLDAsYS5sZW5ndGgsbnVsbCxudWxsKSkKdD1jK2IubGVu
+Z3RoCmlmKHQ+YS5sZW5ndGgpcmV0dXJuITEKcmV0dXJuIGI9PT1hLnN1YnN0cmluZyhjLHQpfSwKbjpm
+dW5jdGlvbihhLGIpe3JldHVybiB0aGlzLlFpKGEsYiwwKX0sCk5qOmZ1bmN0aW9uKGEsYixjKXtpZihj
+PT1udWxsKWM9YS5sZW5ndGgKaWYoYjwwKXRocm93IEguYihQLk83KGIsbnVsbCkpCmlmKGI+Yyl0aHJv
+dyBILmIoUC5PNyhiLG51bGwpKQppZihjPmEubGVuZ3RoKXRocm93IEguYihQLk83KGMsbnVsbCkpCnJl
+dHVybiBhLnN1YnN0cmluZyhiLGMpfSwKRzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLk5qKGEsYixu
+dWxsKX0sCmhjOmZ1bmN0aW9uKGEpe3JldHVybiBhLnRvTG93ZXJDYXNlKCl9LApiUzpmdW5jdGlvbihh
+KXt2YXIgdCxzLHIscT1hLnRyaW0oKSxwPXEubGVuZ3RoCmlmKHA9PT0wKXJldHVybiBxCmlmKHRoaXMu
+VyhxLDApPT09MTMzKXt0PUoubW0ocSwxKQppZih0PT09cClyZXR1cm4iIn1lbHNlIHQ9MApzPXAtMQpy
+PXRoaXMubShxLHMpPT09MTMzP0ouYzEocSxzKTpwCmlmKHQ9PT0wJiZyPT09cClyZXR1cm4gcQpyZXR1
+cm4gcS5zdWJzdHJpbmcodCxyKX0sCkl4OmZ1bmN0aW9uKGEsYil7dmFyIHQscwppZigwPj1iKXJldHVy
+biIiCmlmKGI9PT0xfHxhLmxlbmd0aD09PTApcmV0dXJuIGEKaWYoYiE9PWI+Pj4wKXRocm93IEguYihD
+LkVxKQpmb3IodD1hLHM9IiI7ITA7KXtpZigoYiYxKT09PTEpcz10K3MKYj1iPj4+MQppZihiPT09MCli
+cmVhawp0Kz10fXJldHVybiBzfSwKWFU6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0CmlmKGM8MHx8Yz5hLmxl
+bmd0aCl0aHJvdyBILmIoUC5URShjLDAsYS5sZW5ndGgsbnVsbCxudWxsKSkKdD1hLmluZGV4T2YoYixj
+KQpyZXR1cm4gdH0sCk9ZOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuWFUoYSxiLDApfSwKUGs6ZnVu
+Y3Rpb24oYSxiLGMpe3ZhciB0LHMKaWYoYz09bnVsbCljPWEubGVuZ3RoCmVsc2UgaWYoYzwwfHxjPmEu
+bGVuZ3RoKXRocm93IEguYihQLlRFKGMsMCxhLmxlbmd0aCxudWxsLG51bGwpKQp0PWIubGVuZ3RoCnM9
+YS5sZW5ndGgKaWYoYyt0PnMpYz1zLXQKcmV0dXJuIGEubGFzdEluZGV4T2YoYixjKX0sCmNuOmZ1bmN0
+aW9uKGEsYil7cmV0dXJuIHRoaXMuUGsoYSxiLG51bGwpfSwKSXM6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0
+PWEubGVuZ3RoCmlmKGM+dCl0aHJvdyBILmIoUC5URShjLDAsdCxudWxsLG51bGwpKQpyZXR1cm4gSC5t
+MihhLGIsYyl9LAp0ZzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLklzKGEsYiwwKX0sCnc6ZnVuY3Rp
+b24oYSl7cmV0dXJuIGF9LApnaU86ZnVuY3Rpb24oYSl7dmFyIHQscyxyCmZvcih0PWEubGVuZ3RoLHM9
+MCxyPTA7cjx0Oysrcil7cz01MzY4NzA5MTEmcythLmNoYXJDb2RlQXQocikKcz01MzY4NzA5MTEmcyso
+KDUyNDI4NyZzKTw8MTApCnNePXM+PjZ9cz01MzY4NzA5MTEmcysoKDY3MTA4ODYzJnMpPDwzKQpzXj1z
+Pj4xMQpyZXR1cm4gNTM2ODcwOTExJnMrKCgxNjM4MyZzKTw8MTUpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0
+dXJuIGEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIpe0gudVAoYikKaWYoYj49YS5sZW5ndGh8fCExKXRo
+cm93IEguYihILkhZKGEsYikpCnJldHVybiBhW2JdfSwKJGl2WDoxLAokaXFVOjF9CkgubmQucHJvdG90
+eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgdD0iTGF0ZUluaXRpYWxpemF0aW9uRXJyb3I6ICIrdGhpcy5h
+CnJldHVybiB0fX0KSC5xai5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLmxl
+bmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gQy54Qi5tKHRoaXMuYSxILnVQKGIpKX19CkguYlEu
+cHJvdG90eXBlPXt9CkguYUwucHJvdG90eXBlPXsKZ2t6OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMKcmV0
+dXJuIG5ldyBILmE3KHQsdC5nQSh0KSxILkxoKHQpLkMoImE3PGFMLkU+IikpfSwKelY6ZnVuY3Rpb24o
+YSxiKXt2YXIgdCxzLHIscT10aGlzLHA9cS5nQShxKQppZihiLmxlbmd0aCE9PTApe2lmKHA9PT0wKXJl
+dHVybiIiCnQ9SC5FaihxLkUoMCwwKSkKaWYocCE9PXEuZ0EocSkpdGhyb3cgSC5iKFAuYTQocSkpCmZv
+cihzPXQscj0xO3I8cDsrK3Ipe3M9cytiK0guRWoocS5FKDAscikpCmlmKHAhPT1xLmdBKHEpKXRocm93
+IEguYihQLmE0KHEpKX1yZXR1cm4gcy5jaGFyQ29kZUF0KDApPT0wP3M6c31lbHNle2ZvcihyPTAscz0i
+IjtyPHA7KytyKXtzKz1ILkVqKHEuRSgwLHIpKQppZihwIT09cS5nQShxKSl0aHJvdyBILmIoUC5hNChx
+KSl9cmV0dXJuIHMuY2hhckNvZGVBdCgwKT09MD9zOnN9fSwKZXY6ZnVuY3Rpb24oYSxiKXtyZXR1cm4g
+dGhpcy5HRygwLEguTGgodGhpcykuQygiYTIoYUwuRSkiKS5hKGIpKX0sCkUyOmZ1bmN0aW9uKGEsYixj
+KXt2YXIgdD1ILkxoKHRoaXMpCnJldHVybiBuZXcgSC5sSih0aGlzLHQuS3EoYykuQygiMShhTC5FKSIp
+LmEoYiksdC5DKCJAPGFMLkU+IikuS3EoYykuQygibEo8MSwyPiIpKX19CkgubkgucHJvdG90eXBlPXsK
+Z1VEOmZ1bmN0aW9uKCl7dmFyIHQ9Si5IbSh0aGlzLmEpLHM9dGhpcy5jCmlmKHM9PW51bGx8fHM+dCly
+ZXR1cm4gdApyZXR1cm4gc30sCmdBczpmdW5jdGlvbigpe3ZhciB0PUouSG0odGhpcy5hKSxzPXRoaXMu
+YgppZihzPnQpcmV0dXJuIHQKcmV0dXJuIHN9LApnQTpmdW5jdGlvbihhKXt2YXIgdCxzPUouSG0odGhp
+cy5hKSxyPXRoaXMuYgppZihyPj1zKXJldHVybiAwCnQ9dGhpcy5jCmlmKHQ9PW51bGx8fHQ+PXMpcmV0
+dXJuIHMtcgppZih0eXBlb2YgdCE9PSJudW1iZXIiKXJldHVybiB0LkhOKCkKcmV0dXJuIHQtcn0sCkU6
+ZnVuY3Rpb24oYSxiKXt2YXIgdD10aGlzLHM9dC5nQXMoKStiCmlmKGI8MHx8cz49dC5nVUQoKSl0aHJv
+dyBILmIoUC5DZihiLHQsImluZGV4IixudWxsLG51bGwpKQpyZXR1cm4gSi5HQSh0LmEscyl9fQpILmE3
+LnByb3RvdHlwZT17CmdsOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5kCnJldHVybiB0fSwKRjpmdW5jdGlv
+bigpe3ZhciB0LHM9dGhpcyxyPXMuYSxxPUouVTYocikscD1xLmdBKHIpCmlmKHMuYiE9PXApdGhyb3cg
+SC5iKFAuYTQocikpCnQ9cy5jCmlmKHQ+PXApe3Muc0kobnVsbCkKcmV0dXJuITF9cy5zSShxLkUocix0
+KSk7KytzLmMKcmV0dXJuITB9LApzSTpmdW5jdGlvbihhKXt0aGlzLmQ9dGhpcy4kdGkuQygiMT8iKS5h
+KGEpfSwKJGlBbjoxfQpILmkxLnByb3RvdHlwZT17CmdrejpmdW5jdGlvbihhKXt2YXIgdD1ILkxoKHRo
+aXMpCnJldHVybiBuZXcgSC5NSChKLklUKHRoaXMuYSksdGhpcy5iLHQuQygiQDwxPiIpLktxKHQuUVsx
+XSkuQygiTUg8MSwyPiIpKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiBKLkhtKHRoaXMuYSl9fQpILnh5
+LnByb3RvdHlwZT17JGliUToxfQpILk1ILnByb3RvdHlwZT17CkY6ZnVuY3Rpb24oKXt2YXIgdD10aGlz
+LHM9dC5iCmlmKHMuRigpKXt0LnNJKHQuYy4kMShzLmdsKCkpKQpyZXR1cm4hMH10LnNJKG51bGwpCnJl
+dHVybiExfSwKZ2w6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLmEKcmV0dXJuIHR9LApzSTpmdW5jdGlvbihh
+KXt0aGlzLmE9dGhpcy4kdGkuQygiMj8iKS5hKGEpfX0KSC5sSi5wcm90b3R5cGU9ewpnQTpmdW5jdGlv
+bihhKXtyZXR1cm4gSi5IbSh0aGlzLmEpfSwKRTpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmIuJDEo
+Si5HQSh0aGlzLmEsYikpfX0KSC5VNS5wcm90b3R5cGU9ewpna3o6ZnVuY3Rpb24oYSl7cmV0dXJuIG5l
+dyBILlNPKEouSVQodGhpcy5hKSx0aGlzLmIsdGhpcy4kdGkuQygiU088MT4iKSl9fQpILlNPLnByb3Rv
+dHlwZT17CkY6ZnVuY3Rpb24oKXt2YXIgdCxzCmZvcih0PXRoaXMuYSxzPXRoaXMuYjt0LkYoKTspaWYo
+SC5vVChzLiQxKHQuZ2woKSkpKXJldHVybiEwCnJldHVybiExfSwKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4g
+dGhpcy5hLmdsKCl9fQpILlNVLnByb3RvdHlwZT17fQpILlJlLnByb3RvdHlwZT17Clk6ZnVuY3Rpb24o
+YSxiLGMpe0guTGgodGhpcykuQygiUmUuRSIpLmEoYykKdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBtb2Rp
+ZnkgYW4gdW5tb2RpZmlhYmxlIGxpc3QiKSl9fQpILncyLnByb3RvdHlwZT17fQpILnd2LnByb3RvdHlw
+ZT17CmdpTzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLl9oYXNoQ29kZQppZih0IT1udWxsKXJldHVybiB0
+CnQ9NTM2ODcwOTExJjY2NDU5NypKLmhmKHRoaXMuYSkKdGhpcy5faGFzaENvZGU9dApyZXR1cm4gdH0s
+Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuJ1N5bWJvbCgiJytILkVqKHRoaXMuYSkrJyIpJ30sCkROOmZ1bmN0
+aW9uKGEsYil7aWYoYj09bnVsbClyZXR1cm4hMQpyZXR1cm4gYiBpbnN0YW5jZW9mIEgud3YmJnRoaXMu
+YT09Yi5hfSwKJGlHRDoxfQpILlBELnByb3RvdHlwZT17fQpILldVLnByb3RvdHlwZT17Cnc6ZnVuY3Rp
+b24oYSl7cmV0dXJuIFAubk8odGhpcyl9LApZOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1ILkxoKHRoaXMp
+CnQuYy5hKGIpCnQuUVsxXS5hKGMpCkguZGMoKX0sCmdQdTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5x
+NChhLEguTGgodGhpcykuQygiTjM8MSwyPiIpKX0sCnE0OmZ1bmN0aW9uKGEsYil7dmFyIHQ9dGhpcwpy
+ZXR1cm4gUC5sMChmdW5jdGlvbigpe3ZhciBzPWEKdmFyIHI9MCxxPTEscCxvLG4sbSxsCnJldHVybiBm
+dW5jdGlvbiAkYXN5bmMkZ1B1KGMsZCl7aWYoYz09PTEpe3A9ZApyPXF9d2hpbGUodHJ1ZSlzd2l0Y2go
+cil7Y2FzZSAwOm89dC5nVigpLG89by5na3oobyksbj1ILkxoKHQpLG49bi5DKCJAPDE+IikuS3Eobi5R
+WzFdKS5DKCJOMzwxLDI+IikKY2FzZSAyOmlmKCFvLkYoKSl7cj0zCmJyZWFrfW09by5nbCgpCmw9dC5x
+KDAsbSkKbC50b1N0cmluZwpyPTQKcmV0dXJuIG5ldyBQLk4zKG0sbCxuKQpjYXNlIDQ6cj0yCmJyZWFr
+CmNhc2UgMzpyZXR1cm4gUC5UaCgpCmNhc2UgMTpyZXR1cm4gUC5ZbShwKX19fSxiKX0sCiRpWjA6MX0K
+SC5MUC5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hfSwKeDQ6ZnVuY3Rpb24o
+YSl7aWYodHlwZW9mIGEhPSJzdHJpbmciKXJldHVybiExCmlmKCJfX3Byb3RvX18iPT09YSlyZXR1cm4h
+MQpyZXR1cm4gdGhpcy5iLmhhc093blByb3BlcnR5KGEpfSwKcTpmdW5jdGlvbihhLGIpe2lmKCF0aGlz
+Lng0KGIpKXJldHVybiBudWxsCnJldHVybiB0aGlzLkQoYil9LApEOmZ1bmN0aW9uKGEpe3JldHVybiB0
+aGlzLmJbSC5oKGEpXX0sCks6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwPUguTGgodGhpcykKcC5D
+KCJ+KDEsMikiKS5hKGIpCnQ9dGhpcy5jCmZvcihzPXQubGVuZ3RoLHA9cC5RWzFdLHI9MDtyPHM7Kyty
+KXtxPXRbcl0KYi4kMihxLHAuYSh0aGlzLkQocSkpKX19LApnVjpmdW5jdGlvbigpe3JldHVybiBuZXcg
+SC5YUih0aGlzLEguTGgodGhpcykuQygiWFI8MT4iKSl9fQpILlhSLnByb3RvdHlwZT17CmdrejpmdW5j
+dGlvbihhKXt2YXIgdD10aGlzLmEuYwpyZXR1cm4gbmV3IEoubTEodCx0Lmxlbmd0aCxILnQ2KHQpLkMo
+Im0xPDE+IikpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5jLmxlbmd0aH19CkguTEkucHJv
+dG90eXBlPXsKZ1dhOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5hCnJldHVybiB0fSwKZ25kOmZ1bmN0aW9u
+KCl7dmFyIHQscyxyLHEscD10aGlzCmlmKHAuYz09PTEpcmV0dXJuIEMuZG4KdD1wLmQKcz10Lmxlbmd0
+aC1wLmUubGVuZ3RoLXAuZgppZihzPT09MClyZXR1cm4gQy5kbgpyPVtdCmZvcihxPTA7cTxzOysrcSl7
+aWYocT49dC5sZW5ndGgpcmV0dXJuIEguT0godCxxKQpyLnB1c2godFtxXSl9cmV0dXJuIEouekMocil9
+LApnVm06ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwLG8sbixtLGw9dGhpcwppZihsLmMhPT0wKXJldHVy
+biBDLkR4CnQ9bC5lCnM9dC5sZW5ndGgKcj1sLmQKcT1yLmxlbmd0aC1zLWwuZgppZihzPT09MClyZXR1
+cm4gQy5EeApwPW5ldyBILk41KHUuZW8pCmZvcihvPTA7bzxzOysrbyl7aWYobz49dC5sZW5ndGgpcmV0
+dXJuIEguT0godCxvKQpuPXRbb10KbT1xK28KaWYobTwwfHxtPj1yLmxlbmd0aClyZXR1cm4gSC5PSChy
+LG0pCnAuWSgwLG5ldyBILnd2KG4pLHJbbV0pfXJldHVybiBuZXcgSC5QRChwLHUuZ0YpfSwKJGl2UTox
+fQpILkNqLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHQKSC5oKGEpCnQ9dGhpcy5hCnQu
+Yj10LmIrIiQiK0guRWooYSkKQy5ObS5pKHRoaXMuYixhKQpDLk5tLmkodGhpcy5jLGIpOysrdC5hfSwK
+JFM6MTJ9CkguZjkucHJvdG90eXBlPXsKcVM6ZnVuY3Rpb24oYSl7dmFyIHQscyxyPXRoaXMscT1uZXcg
+UmVnRXhwKHIuYSkuZXhlYyhhKQppZihxPT1udWxsKXJldHVybiBudWxsCnQ9T2JqZWN0LmNyZWF0ZShu
+dWxsKQpzPXIuYgppZihzIT09LTEpdC5hcmd1bWVudHM9cVtzKzFdCnM9ci5jCmlmKHMhPT0tMSl0LmFy
+Z3VtZW50c0V4cHI9cVtzKzFdCnM9ci5kCmlmKHMhPT0tMSl0LmV4cHI9cVtzKzFdCnM9ci5lCmlmKHMh
+PT0tMSl0Lm1ldGhvZD1xW3MrMV0Kcz1yLmYKaWYocyE9PS0xKXQucmVjZWl2ZXI9cVtzKzFdCnJldHVy
+biB0fX0KSC5XMC5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYgppZih0PT1udWxs
+KXJldHVybiJOb1N1Y2hNZXRob2RFcnJvcjogIitILkVqKHRoaXMuYSkKcmV0dXJuIk5vU3VjaE1ldGhv
+ZEVycm9yOiBtZXRob2Qgbm90IGZvdW5kOiAnIit0KyInIG9uIG51bGwifX0KSC5hei5wcm90b3R5cGU9
+ewp3OmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcyxyPSJOb1N1Y2hNZXRob2RFcnJvcjogbWV0aG9kIG5v
+dCBmb3VuZDogJyIscT1zLmIKaWYocT09bnVsbClyZXR1cm4iTm9TdWNoTWV0aG9kRXJyb3I6ICIrSC5F
+aihzLmEpCnQ9cy5jCmlmKHQ9PW51bGwpcmV0dXJuIHIrcSsiJyAoIitILkVqKHMuYSkrIikiCnJldHVy
+biByK3ErIicgb24gJyIrdCsiJyAoIitILkVqKHMuYSkrIikifX0KSC52Vi5wcm90b3R5cGU9ewp3OmZ1
+bmN0aW9uKGEpe3ZhciB0PXRoaXMuYQpyZXR1cm4gdC5sZW5ndGg9PT0wPyJFcnJvciI6IkVycm9yOiAi
+K3R9fQpILmJxLnByb3RvdHlwZT17fQpILkFtLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe2lmKHUu
+Vy5iKGEpKWlmKGEuJHRocm93bkpzRXJyb3I9PW51bGwpYS4kdGhyb3duSnNFcnJvcj10aGlzLmEKcmV0
+dXJuIGF9LAokUzo1fQpILlhPLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzLmIK
+aWYocyE9bnVsbClyZXR1cm4gcwpzPXRoaXMuYQp0PXMhPT1udWxsJiZ0eXBlb2Ygcz09PSJvYmplY3Qi
+P3Muc3RhY2s6bnVsbApyZXR1cm4gdGhpcy5iPXQ9PW51bGw/IiI6dH0sCiRpR3o6MX0KSC52LnByb3Rv
+dHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5jb25zdHJ1Y3RvcixzPXQ9PW51bGw/bnVsbDp0
+Lm5hbWUKcmV0dXJuIkNsb3N1cmUgJyIrSC5OUShzPT1udWxsPyJ1bmtub3duIjpzKSsiJyJ9LAokaUVI
+OjEsCmdRbDpmdW5jdGlvbigpe3JldHVybiB0aGlzfSwKJEM6IiQxIiwKJFI6MSwKJEQ6bnVsbH0KSC5s
+Yy5wcm90b3R5cGU9e30KSC56eC5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuJHN0
+YXRpY19uYW1lCmlmKHQ9PW51bGwpcmV0dXJuIkNsb3N1cmUgb2YgdW5rbm93biBzdGF0aWMgbWV0aG9k
+IgpyZXR1cm4iQ2xvc3VyZSAnIitILk5RKHQpKyInIn19CkguclQucHJvdG90eXBlPXsKRE46ZnVuY3Rp
+b24oYSxiKXt2YXIgdD10aGlzCmlmKGI9PW51bGwpcmV0dXJuITEKaWYodD09PWIpcmV0dXJuITAKaWYo
+IShiIGluc3RhbmNlb2YgSC5yVCkpcmV0dXJuITEKcmV0dXJuIHQuYT09PWIuYSYmdC5iPT09Yi5iJiZ0
+LmM9PT1iLmN9LApnaU86ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzLmMKaWYocz09bnVsbCl0PUguZVEo
+dGhpcy5hKQplbHNlIHQ9dHlwZW9mIHMhPT0ib2JqZWN0Ij9KLmhmKHMpOkguZVEocykKcmV0dXJuKHRe
+SC5lUSh0aGlzLmIpKT4+PjB9LAp3OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYwppZih0PT1udWxsKXQ9
+dGhpcy5hCnJldHVybiJDbG9zdXJlICciK0guRWoodGhpcy5kKSsiJyBvZiAiKygiSW5zdGFuY2Ugb2Yg
+JyIrSC5FaihILk0odCkpKyInIil9fQpILkVxLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJu
+IlJ1bnRpbWVFcnJvcjogIitILkVqKHRoaXMuYSl9fQpILmtZLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24o
+YSl7cmV0dXJuIkFzc2VydGlvbiBmYWlsZWQ6ICIrUC5wKHRoaXMuYSl9fQpILk41LnByb3RvdHlwZT17
+CmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmF9LApnVjpmdW5jdGlvbigpe3JldHVybiBuZXcgSC5p
+NSh0aGlzLEguTGgodGhpcykuQygiaTU8MT4iKSl9LAp4NDpmdW5jdGlvbihhKXt2YXIgdCxzCmlmKHR5
+cGVvZiBhPT0ic3RyaW5nIil7dD10aGlzLmIKaWYodD09bnVsbClyZXR1cm4hMQpyZXR1cm4gdGhpcy5Y
+dSh0LGEpfWVsc2V7cz10aGlzLkNYKGEpCnJldHVybiBzfX0sCkNYOmZ1bmN0aW9uKGEpe3ZhciB0PXRo
+aXMuZAppZih0PT1udWxsKXJldHVybiExCnJldHVybiB0aGlzLkZoKHRoaXMuQnQodCxKLmhmKGEpJjB4
+M2ZmZmZmZiksYSk+PTB9LApxOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscD10aGlzLG89bnVsbApp
+Zih0eXBlb2YgYj09InN0cmluZyIpe3Q9cC5iCmlmKHQ9PW51bGwpcmV0dXJuIG8Kcz1wLmoyKHQsYikK
+cj1zPT1udWxsP286cy5iCnJldHVybiByfWVsc2UgaWYodHlwZW9mIGI9PSJudW1iZXIiJiYoYiYweDNm
+ZmZmZmYpPT09Yil7cT1wLmMKaWYocT09bnVsbClyZXR1cm4gbwpzPXAuajIocSxiKQpyPXM9PW51bGw/
+bzpzLmIKcmV0dXJuIHJ9ZWxzZSByZXR1cm4gcC5hYShiKX0sCmFhOmZ1bmN0aW9uKGEpe3ZhciB0LHMs
+cj10aGlzLmQKaWYocj09bnVsbClyZXR1cm4gbnVsbAp0PXRoaXMuQnQocixKLmhmKGEpJjB4M2ZmZmZm
+ZikKcz10aGlzLkZoKHQsYSkKaWYoczwwKXJldHVybiBudWxsCnJldHVybiB0W3NdLmJ9LApZOmZ1bmN0
+aW9uKGEsYixjKXt2YXIgdCxzLHIscSxwLG8sbj10aGlzLG09SC5MaChuKQptLmMuYShiKQptLlFbMV0u
+YShjKQppZih0eXBlb2YgYj09InN0cmluZyIpe3Q9bi5iCm4uRUgodD09bnVsbD9uLmI9bi56SygpOnQs
+YixjKX1lbHNlIGlmKHR5cGVvZiBiPT0ibnVtYmVyIiYmKGImMHgzZmZmZmZmKT09PWIpe3M9bi5jCm4u
+RUgocz09bnVsbD9uLmM9bi56SygpOnMsYixjKX1lbHNle3I9bi5kCmlmKHI9PW51bGwpcj1uLmQ9bi56
+SygpCnE9Si5oZihiKSYweDNmZmZmZmYKcD1uLkJ0KHIscSkKaWYocD09bnVsbCluLkVJKHIscSxbbi5I
+bihiLGMpXSkKZWxzZXtvPW4uRmgocCxiKQppZihvPj0wKXBbb10uYj1jCmVsc2UgcC5wdXNoKG4uSG4o
+YixjKSl9fX0sCks6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9dGhpcwpILkxoKHIpLkMoIn4oMSwyKSIp
+LmEoYikKdD1yLmUKcz1yLnIKZm9yKDt0IT1udWxsOyl7Yi4kMih0LmEsdC5iKQppZihzIT09ci5yKXRo
+cm93IEguYihQLmE0KHIpKQp0PXQuY319LApFSDpmdW5jdGlvbihhLGIsYyl7dmFyIHQscz10aGlzLHI9
+SC5MaChzKQpyLmMuYShiKQpyLlFbMV0uYShjKQp0PXMuajIoYSxiKQppZih0PT1udWxsKXMuRUkoYSxi
+LHMuSG4oYixjKSkKZWxzZSB0LmI9Y30sCmtzOmZ1bmN0aW9uKCl7dGhpcy5yPXRoaXMucisxJjY3MTA4
+ODYzfSwKSG46ZnVuY3Rpb24oYSxiKXt2YXIgdD10aGlzLHM9SC5MaCh0KSxyPW5ldyBILmRiKHMuYy5h
+KGEpLHMuUVsxXS5hKGIpKQppZih0LmU9PW51bGwpdC5lPXQuZj1yCmVsc2V7cz10LmYKcy50b1N0cmlu
+ZwpyLmQ9cwp0LmY9cy5jPXJ9Kyt0LmEKdC5rcygpCnJldHVybiByfSwKRmg6ZnVuY3Rpb24oYSxiKXt2
+YXIgdCxzCmlmKGE9PW51bGwpcmV0dXJuLTEKdD1hLmxlbmd0aApmb3Iocz0wO3M8dDsrK3MpaWYoSi5S
+TShhW3NdLmEsYikpcmV0dXJuIHMKcmV0dXJuLTF9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiBQLm5PKHRo
+aXMpfSwKajI6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gYVtiXX0sCkJ0OmZ1bmN0aW9uKGEsYil7cmV0dXJu
+IGFbYl19LApFSTpmdW5jdGlvbihhLGIsYyl7YVtiXT1jfSwKcm46ZnVuY3Rpb24oYSxiKXtkZWxldGUg
+YVtiXX0sClh1OmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuajIoYSxiKSE9bnVsbH0sCnpLOmZ1bmN0
+aW9uKCl7dmFyIHQ9Ijxub24taWRlbnRpZmllci1rZXk+IixzPU9iamVjdC5jcmVhdGUobnVsbCkKdGhp
+cy5FSShzLHQscykKdGhpcy5ybihzLHQpCnJldHVybiBzfSwKJGlGbzoxfQpILmRiLnByb3RvdHlwZT17
+fQpILmk1LnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEuYX0sCmdrejpmdW5j
+dGlvbihhKXt2YXIgdD10aGlzLmEscz1uZXcgSC5ONih0LHQucix0aGlzLiR0aS5DKCJONjwxPiIpKQpz
+LmM9dC5lCnJldHVybiBzfSwKdGc6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5hLng0KGIpfX0KSC5O
+Ni5wcm90b3R5cGU9ewpnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmR9LApGOmZ1bmN0aW9uKCl7dmFy
+IHQscz10aGlzLHI9cy5hCmlmKHMuYiE9PXIucil0aHJvdyBILmIoUC5hNChyKSkKdD1zLmMKaWYodD09
+bnVsbCl7cy5zcVkobnVsbCkKcmV0dXJuITF9ZWxzZXtzLnNxWSh0LmEpCnMuYz10LmMKcmV0dXJuITB9
+fSwKc3FZOmZ1bmN0aW9uKGEpe3RoaXMuZD10aGlzLiR0aS5DKCIxPyIpLmEoYSl9LAokaUFuOjF9Ckgu
+ZEMucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYShhKX0sCiRTOjV9Ckgud04u
+cHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5hKGEsYil9LAokUzoyMX0KSC5W
+WC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hKEguaChhKSl9LAokUzo0N30K
+SC5WUi5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJSZWdFeHAvIit0aGlzLmErIi8iK3Ro
+aXMuYi5mbGFnc30sCmdIYzpmdW5jdGlvbigpe3ZhciB0PXRoaXMscz10LmMKaWYocyE9bnVsbClyZXR1
+cm4gcwpzPXQuYgpyZXR1cm4gdC5jPUgudjQodC5hLHMubXVsdGlsaW5lLCFzLmlnbm9yZUNhc2Uscy51
+bmljb2RlLHMuZG90QWxsLCEwKX0sCmRkOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBILktXKHRoaXMs
+YiwwKX0sClVaOmZ1bmN0aW9uKGEsYil7dmFyIHQscz10aGlzLmdIYygpCnMubGFzdEluZGV4PWIKdD1z
+LmV4ZWMoYSkKaWYodD09bnVsbClyZXR1cm4gbnVsbApyZXR1cm4gbmV3IEguRUsodCl9LAokaXZYOjEs
+CiRpd0w6MX0KSC5FSy5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7dmFyIHQKSC51UChiKQp0PXRo
+aXMuYgppZihiPj10Lmxlbmd0aClyZXR1cm4gSC5PSCh0LGIpCnJldHVybiB0W2JdfSwKJGlPZDoxLAok
+aWliOjF9CkguS1cucHJvdG90eXBlPXsKZ2t6OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgSC5QYih0aGlz
+LmEsdGhpcy5iLHRoaXMuYyl9fQpILlBiLnByb3RvdHlwZT17CmdsOmZ1bmN0aW9uKCl7dmFyIHQ9dGhp
+cy5kCnQudG9TdHJpbmcKcmV0dXJuIHR9LApGOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscCxvLG49dGhp
+cyxtPW4uYgppZihtPT1udWxsKXJldHVybiExCnQ9bi5jCnM9bS5sZW5ndGgKaWYodDw9cyl7cj1uLmEK
+cT1yLlVaKG0sdCkKaWYocSE9bnVsbCl7bi5kPXEKdD1xLmIKcD10LmluZGV4Cm89cCt0WzBdLmxlbmd0
+aAppZihwPT09byl7aWYoci5iLnVuaWNvZGUpe3Q9bi5jCnI9dCsxCmlmKHI8cyl7dD1DLnhCLm0obSx0
+KQppZih0Pj01NTI5NiYmdDw9NTYzMTkpe3Q9Qy54Qi5tKG0scikKdD10Pj01NjMyMCYmdDw9NTczNDN9
+ZWxzZSB0PSExfWVsc2UgdD0hMX1lbHNlIHQ9ITEKbz0odD9vKzE6bykrMX1uLmM9bwpyZXR1cm4hMH19
+bi5iPW4uZD1udWxsCnJldHVybiExfSwKJGlBbjoxfQpILnRRLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24o
+YSxiKXtILnVQKGIpCmlmKGIhPT0wKUgudmgoUC5PNyhiLG51bGwpKQpyZXR1cm4gdGhpcy5jfSwKJGlP
+ZDoxfQpILnVuLnByb3RvdHlwZT17CmdrejpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEguU2QodGhpcy5h
+LHRoaXMuYix0aGlzLmMpfX0KSC5TZC5wcm90b3R5cGU9ewpGOmZ1bmN0aW9uKCl7dmFyIHQscyxyPXRo
+aXMscT1yLmMscD1yLmIsbz1wLmxlbmd0aCxuPXIuYSxtPW4ubGVuZ3RoCmlmKHErbz5tKXtyLmQ9bnVs
+bApyZXR1cm4hMX10PW4uaW5kZXhPZihwLHEpCmlmKHQ8MCl7ci5jPW0rMQpyLmQ9bnVsbApyZXR1cm4h
+MX1zPXQrbwpyLmQ9bmV3IEgudFEodCxwKQpyLmM9cz09PXIuYz9zKzE6cwpyZXR1cm4hMH0sCmdsOmZ1
+bmN0aW9uKCl7dmFyIHQ9dGhpcy5kCnQudG9TdHJpbmcKcmV0dXJuIHR9LAokaUFuOjF9CkguRVQucHJv
+dG90eXBlPXskaUVUOjEsJGlBUzoxfQpILmIwLnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVy
+biBhLmxlbmd0aH0sCiRpWGo6MX0KSC5EZy5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7SC51UChi
+KQpILm9kKGIsYSxhLmxlbmd0aCkKcmV0dXJuIGFbYl19LApZOmZ1bmN0aW9uKGEsYixjKXtILkdIKGMp
+Ckgub2QoYixhLGEubGVuZ3RoKQphW2JdPWN9LAokaWJROjEsCiRpY1g6MSwKJGl6TToxfQpILlBnLnBy
+b3RvdHlwZT17Clk6ZnVuY3Rpb24oYSxiLGMpe0gudVAoYykKSC5vZChiLGEsYS5sZW5ndGgpCmFbYl09
+Y30sCiRpYlE6MSwKJGljWDoxLAokaXpNOjF9CkgueGoucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIp
+e0gudVAoYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfX0KSC5kRS5wcm90b3R5cGU9ewpx
+OmZ1bmN0aW9uKGEsYil7SC51UChiKQpILm9kKGIsYSxhLmxlbmd0aCkKcmV0dXJuIGFbYl19fQpILlpB
+LnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtILnVQKGIpCkgub2QoYixhLGEubGVuZ3RoKQpyZXR1
+cm4gYVtiXX19CkguZFQucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe0gudVAoYikKSC5vZChiLGEs
+YS5sZW5ndGgpCnJldHVybiBhW2JdfX0KSC5QcS5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7SC51
+UChiKQpILm9kKGIsYSxhLmxlbmd0aCkKcmV0dXJuIGFbYl19fQpILmVFLnByb3RvdHlwZT17CmdBOmZ1
+bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXtILnVQKGIpCkgub2QoYixh
+LGEubGVuZ3RoKQpyZXR1cm4gYVtiXX19CkguVjYucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0
+dXJuIGEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIpe0gudVAoYikKSC5vZChiLGEsYS5sZW5ndGgpCnJl
+dHVybiBhW2JdfSwKJGlWNjoxLAokaW42OjF9CkguUkcucHJvdG90eXBlPXt9CkguVlAucHJvdG90eXBl
+PXt9CkguV0IucHJvdG90eXBlPXt9CkguWkcucHJvdG90eXBlPXt9CkguSmMucHJvdG90eXBlPXsKQzpm
+dW5jdGlvbihhKXtyZXR1cm4gSC5jRSh2LnR5cGVVbml2ZXJzZSx0aGlzLGEpfSwKS3E6ZnVuY3Rpb24o
+YSl7cmV0dXJuIEgudjUodi50eXBlVW5pdmVyc2UsdGhpcyxhKX19CkguRy5wcm90b3R5cGU9e30KSC51
+OS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmF9fQpILmlNLnByb3RvdHlwZT17
+fQpQLnRoLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYSxzPXQuYQp0LmE9bnVs
+bApzLiQwKCl9LAokUzoxMX0KUC5oYS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdCxzCnRo
+aXMuYS5hPXUuTS5hKGEpCnQ9dGhpcy5iCnM9dGhpcy5jCnQuZmlyc3RDaGlsZD90LnJlbW92ZUNoaWxk
+KHMpOnQuYXBwZW5kQ2hpbGQocyl9LAokUzozMH0KUC5Wcy5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigp
+e3RoaXMuYS4kMCgpfSwKJEM6IiQwIiwKJFI6MCwKJFM6MH0KUC5GdC5wcm90b3R5cGU9ewokMDpmdW5j
+dGlvbigpe3RoaXMuYS4kMCgpfSwKJEM6IiQwIiwKJFI6MCwKJFM6MH0KUC5XMy5wcm90b3R5cGU9ewpD
+WTpmdW5jdGlvbihhLGIpe2lmKHNlbGYuc2V0VGltZW91dCE9bnVsbClzZWxmLnNldFRpbWVvdXQoSC50
+UihuZXcgUC55SCh0aGlzLGIpLDApLGEpCmVsc2UgdGhyb3cgSC5iKFAuTDQoImBzZXRUaW1lb3V0KClg
+IG5vdCBmb3VuZC4iKSl9fQpQLnlILnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7dGhpcy5iLiQwKCl9
+LAokQzoiJDAiLAokUjowLAokUzoxfQpQLmloLnByb3RvdHlwZT17CmFNOmZ1bmN0aW9uKGEsYil7dmFy
+IHQscz10aGlzLHI9cy4kdGkKci5DKCIxLz8iKS5hKGIpCmlmKCFzLmIpcy5hLlhmKGIpCmVsc2V7dD1z
+LmEKaWYoci5DKCJiODwxPiIpLmIoYikpdC5jVShiKQplbHNlIHQuWDIoci5jLmEoYikpfX0sCncwOmZ1
+bmN0aW9uKGEsYil7dmFyIHQKaWYoYj09bnVsbCliPVAudjAoYSkKdD10aGlzLmEKaWYodGhpcy5iKXQu
+WkwoYSxiKQplbHNlIHQuTmsoYSxiKX19ClAuV00ucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0
+dXJuIHRoaXMuYS4kMigwLGEpfSwKJFM6Mjl9ClAuU1gucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxi
+KXt0aGlzLmEuJDIoMSxuZXcgSC5icShhLHUubC5hKGIpKSl9LAokQzoiJDIiLAokUjoyLAokUzoyNn0K
+UC5Hcy5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3RoaXMuYShILnVQKGEpLGIpfSwKJFM6MzJ9
+ClAuRnkucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iSXRlcmF0aW9uTWFya2VyKCIrdGhp
+cy5iKyIsICIrSC5Faih0aGlzLmEpKyIpIn19ClAuR1YucHJvdG90eXBlPXsKZ2w6ZnVuY3Rpb24oKXt2
+YXIgdD10aGlzLmMKaWYodD09bnVsbClyZXR1cm4gdGhpcy4kdGkuYy5hKHRoaXMuYikKcmV0dXJuIHQu
+Z2woKX0sCkY6ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwLG8sbj10aGlzCmZvcih0PW4uJHRpLkMoIkFu
+PDE+Iik7ITA7KXtzPW4uYwppZihzIT1udWxsKWlmKHMuRigpKXJldHVybiEwCmVsc2Ugbi5zWDkobnVs
+bCkKcj1mdW5jdGlvbihhLGIsYyl7dmFyIG0sbD1iCndoaWxlKHRydWUpdHJ5e3JldHVybiBhKGwsbSl9
+Y2F0Y2goayl7bT1rCmw9Y319KG4uYSwwLDEpCmlmKHIgaW5zdGFuY2VvZiBQLkZ5KXtxPXIuYgppZihx
+PT09Mil7cD1uLmQKaWYocD09bnVsbHx8cC5sZW5ndGg9PT0wKXtuLnNFQyhudWxsKQpyZXR1cm4hMX1p
+ZigwPj1wLmxlbmd0aClyZXR1cm4gSC5PSChwLC0xKQpuLmE9cC5wb3AoKQpjb250aW51ZX1lbHNle3M9
+ci5hCmlmKHE9PT0zKXRocm93IHMKZWxzZXtvPXQuYShKLklUKHMpKQppZihvIGluc3RhbmNlb2YgUC5H
+Vil7cz1uLmQKaWYocz09bnVsbClzPW4uZD1bXQpDLk5tLmkocyxuLmEpCm4uYT1vLmEKY29udGludWV9
+ZWxzZXtuLnNYOShvKQpjb250aW51ZX19fX1lbHNle24uc0VDKHIpCnJldHVybiEwfX1yZXR1cm4hMX0s
+CnNFQzpmdW5jdGlvbihhKXt0aGlzLmI9dGhpcy4kdGkuQygiMT8iKS5hKGEpfSwKc1g5OmZ1bmN0aW9u
+KGEpe3RoaXMuYz10aGlzLiR0aS5DKCJBbjwxPj8iKS5hKGEpfSwKJGlBbjoxfQpQLnE0LnByb3RvdHlw
+ZT17CmdrejpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuR1YodGhpcy5hKCksdGhpcy4kdGkuQygiR1Y8
+MT4iKSl9fQpQLmI4LnByb3RvdHlwZT17fQpQLlBmLnByb3RvdHlwZT17CncwOmZ1bmN0aW9uKGEsYil7
+dmFyIHQKUC5VSShhLCJlcnJvciIsdS5LKQp0PXRoaXMuYQppZih0LmEhPT0wKXRocm93IEguYihQLlBW
+KCJGdXR1cmUgYWxyZWFkeSBjb21wbGV0ZWQiKSkKaWYoYj09bnVsbCliPVAudjAoYSkKdC5OayhhLGIp
+fSwKcG06ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMudzAoYSxudWxsKX19ClAuWmYucHJvdG90eXBlPXsK
+YU06ZnVuY3Rpb24oYSxiKXt2YXIgdCxzPXRoaXMuJHRpCnMuQygiMS8/IikuYShiKQp0PXRoaXMuYQpp
+Zih0LmEhPT0wKXRocm93IEguYihQLlBWKCJGdXR1cmUgYWxyZWFkeSBjb21wbGV0ZWQiKSkKdC5YZihz
+LkMoIjEvIikuYShiKSl9fQpQLkZlLnByb3RvdHlwZT17CkhSOmZ1bmN0aW9uKGEpe2lmKCh0aGlzLmMm
+MTUpIT09NilyZXR1cm4hMApyZXR1cm4gdGhpcy5iLmIuYnYodS5hbC5hKHRoaXMuZCksYS5hLHUueSx1
+LkspfSwKS3c6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5lLHM9dS56LHI9dS5LLHE9dGhpcy4kdGkuQygi
+Mi8iKSxwPXRoaXMuYi5iCmlmKHUuYWcuYih0KSlyZXR1cm4gcS5hKHAucnAodCxhLmEsYS5iLHMscix1
+LmwpKQplbHNlIHJldHVybiBxLmEocC5idih1LmJJLmEodCksYS5hLHMscikpfX0KUC52cy5wcm90b3R5
+cGU9ewpTcTpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHE9dGhpcy4kdGkKcS5LcShjKS5DKCIxLygy
+KSIpLmEoYSkKdD0kLlgzCmlmKHQhPT1DLk5VKXtjLkMoIkA8MC8+IikuS3EocS5jKS5DKCIxKDIpIiku
+YShhKQppZihiIT1udWxsKWI9UC5WSChiLHQpfXM9bmV3IFAudnMoJC5YMyxjLkMoInZzPDA+IikpCnI9
+Yj09bnVsbD8xOjMKdGhpcy54ZihuZXcgUC5GZShzLHIsYSxiLHEuQygiQDwxPiIpLktxKGMpLkMoIkZl
+PDEsMj4iKSkpCnJldHVybiBzfSwKVzc6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5TcShhLG51bGws
+Yil9LApRZDpmdW5jdGlvbihhLGIsYyl7dmFyIHQscz10aGlzLiR0aQpzLktxKGMpLkMoIjEvKDIpIiku
+YShhKQp0PW5ldyBQLnZzKCQuWDMsYy5DKCJ2czwwPiIpKQp0aGlzLnhmKG5ldyBQLkZlKHQsMTksYSxi
+LHMuQygiQDwxPiIpLktxKGMpLkMoIkZlPDEsMj4iKSkpCnJldHVybiB0fSwKT0E6ZnVuY3Rpb24oYSl7
+dmFyIHQscyxyCnUuYjcuYShudWxsKQp0PXRoaXMuJHRpCnM9JC5YMwpyPW5ldyBQLnZzKHMsdCkKaWYo
+cyE9PUMuTlUpYT1QLlZIKGEscykKdGhpcy54ZihuZXcgUC5GZShyLDIsbnVsbCxhLHQuQygiQDwxPiIp
+LktxKHQuYykuQygiRmU8MSwyPiIpKSkKcmV0dXJuIHJ9LAp4ZjpmdW5jdGlvbihhKXt2YXIgdCxzPXRo
+aXMscj1zLmEKaWYocjw9MSl7YS5hPXUuRi5hKHMuYykKcy5jPWF9ZWxzZXtpZihyPT09Mil7dD11LmMu
+YShzLmMpCnI9dC5hCmlmKHI8NCl7dC54ZihhKQpyZXR1cm59cy5hPXIKcy5jPXQuY31QLlRrKG51bGws
+bnVsbCxzLmIsdS5NLmEobmV3IFAuZGEocyxhKSkpfX0sCmpROmZ1bmN0aW9uKGEpe3ZhciB0LHMscixx
+LHAsbyxuPXRoaXMsbT17fQptLmE9YQppZihhPT1udWxsKXJldHVybgp0PW4uYQppZih0PD0xKXtzPXUu
+Ri5hKG4uYykKbi5jPWEKaWYocyE9bnVsbCl7cj1hLmEKZm9yKHE9YTtyIT1udWxsO3E9cixyPXApcD1y
+LmEKcS5hPXN9fWVsc2V7aWYodD09PTIpe289dS5jLmEobi5jKQp0PW8uYQppZih0PDQpe28ualEoYSkK
+cmV0dXJufW4uYT10Cm4uYz1vLmN9bS5hPW4uTjgoYSkKUC5UayhudWxsLG51bGwsbi5iLHUuTS5hKG5l
+dyBQLm9RKG0sbikpKX19LAphaDpmdW5jdGlvbigpe3ZhciB0PXUuRi5hKHRoaXMuYykKdGhpcy5jPW51
+bGwKcmV0dXJuIHRoaXMuTjgodCl9LApOODpmdW5jdGlvbihhKXt2YXIgdCxzLHIKZm9yKHQ9YSxzPW51
+bGw7dCE9bnVsbDtzPXQsdD1yKXtyPXQuYQp0LmE9c31yZXR1cm4gc30sCkhIOmZ1bmN0aW9uKGEpe3Zh
+ciB0LHM9dGhpcyxyPXMuJHRpCnIuQygiMS8iKS5hKGEpCmlmKHIuQygiYjg8MT4iKS5iKGEpKWlmKHIu
+YihhKSlQLkE5KGEscykKZWxzZSBQLmszKGEscykKZWxzZXt0PXMuYWgoKQpyLmMuYShhKQpzLmE9NApz
+LmM9YQpQLkhaKHMsdCl9fSwKWDI6ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzCnMuJHRpLmMuYShhKQp0
+PXMuYWgoKQpzLmE9NApzLmM9YQpQLkhaKHMsdCl9LApaTDpmdW5jdGlvbihhLGIpe3ZhciB0LHMscj10
+aGlzCnUubC5hKGIpCnQ9ci5haCgpCnM9UC5UbChhLGIpCnIuYT04CnIuYz1zClAuSFoocix0KX0sClhm
+OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuJHRpCnQuQygiMS8iKS5hKGEpCmlmKHQuQygiYjg8MT4iKS5i
+KGEpKXt0aGlzLmNVKGEpCnJldHVybn10aGlzLndVKHQuYy5hKGEpKX0sCndVOmZ1bmN0aW9uKGEpe3Zh
+ciB0PXRoaXMKdC4kdGkuYy5hKGEpCnQuYT0xClAuVGsobnVsbCxudWxsLHQuYix1Lk0uYShuZXcgUC5y
+dCh0LGEpKSl9LApjVTpmdW5jdGlvbihhKXt2YXIgdD10aGlzLHM9dC4kdGkKcy5DKCJiODwxPiIpLmEo
+YSkKaWYocy5iKGEpKXtpZihhLmE9PT04KXt0LmE9MQpQLlRrKG51bGwsbnVsbCx0LmIsdS5NLmEobmV3
+IFAuS0YodCxhKSkpfWVsc2UgUC5BOShhLHQpCnJldHVybn1QLmszKGEsdCl9LApOazpmdW5jdGlvbihh
+LGIpe3RoaXMuYT0xClAuVGsobnVsbCxudWxsLHRoaXMuYix1Lk0uYShuZXcgUC5aTCh0aGlzLGEsYikp
+KX0sCiRpYjg6MX0KUC5kYS5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe1AuSFoodGhpcy5hLHRoaXMu
+Yil9LAokUzowfQpQLm9RLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7UC5IWih0aGlzLmIsdGhpcy5h
+LmEpfSwKJFM6MH0KUC5wVi5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEKdC5h
+PTAKdC5ISChhKX0sCiRTOjExfQpQLlU3LnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dS5sLmEo
+YikKdGhpcy5hLlpMKGEsYil9LAokQzoiJDIiLAokUjoyLAokUzozOH0KUC52ci5wcm90b3R5cGU9ewok
+MDpmdW5jdGlvbigpe3RoaXMuYS5aTCh0aGlzLmIsdGhpcy5jKX0sCiRTOjB9ClAucnQucHJvdG90eXBl
+PXsKJDA6ZnVuY3Rpb24oKXt0aGlzLmEuWDIodGhpcy5iKX0sCiRTOjB9ClAuS0YucHJvdG90eXBlPXsK
+JDA6ZnVuY3Rpb24oKXtQLkE5KHRoaXMuYix0aGlzLmEpfSwKJFM6MH0KUC5aTC5wcm90b3R5cGU9ewok
+MDpmdW5jdGlvbigpe3RoaXMuYS5aTCh0aGlzLmIsdGhpcy5jKX0sCiRTOjB9ClAuUlQucHJvdG90eXBl
+PXsKJDA6ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwLG8sbj10aGlzLG09bnVsbAp0cnl7cj1uLmEuYQpt
+PXIuYi5iLnp6KHUuZk8uYShyLmQpLHUueil9Y2F0Y2gocSl7dD1ILlJ1KHEpCnM9SC50cyhxKQppZihu
+LmMpe3I9dS5uLmEobi5iLmEuYykuYQpwPXQKcD1yPT1udWxsP3A9PW51bGw6cj09PXAKcj1wfWVsc2Ug
+cj0hMQpwPW4uYQppZihyKXAuYz11Lm4uYShuLmIuYS5jKQplbHNlIHAuYz1QLlRsKHQscykKcC5iPSEw
+CnJldHVybn1pZihtIGluc3RhbmNlb2YgUC52cyYmbS5hPj00KXtpZihtLmE9PT04KXtyPW4uYQpyLmM9
+dS5uLmEobS5jKQpyLmI9ITB9cmV0dXJufWlmKHUuZC5iKG0pKXtvPW4uYi5hCnI9bi5hCnIuYz1tLlc3
+KG5ldyBQLmpaKG8pLHUueikKci5iPSExfX0sCiRTOjF9ClAualoucHJvdG90eXBlPXsKJDE6ZnVuY3Rp
+b24oYSl7cmV0dXJuIHRoaXMuYX0sCiRTOjM5fQpQLnJxLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7
+dmFyIHQscyxyLHEscCxvLG4sbQp0cnl7cj10aGlzLmEKcT1yLmEKcD1xLiR0aQpvPXAuYwpuPW8uYSh0
+aGlzLmIpCnIuYz1xLmIuYi5idihwLkMoIjIvKDEpIikuYShxLmQpLG4scC5DKCIyLyIpLG8pfWNhdGNo
+KG0pe3Q9SC5SdShtKQpzPUgudHMobSkKcj10aGlzLmEKci5jPVAuVGwodCxzKQpyLmI9ITB9fSwKJFM6
+MX0KUC5SVy5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3ZhciB0LHMscixxLHAsbyxuLG0sbD10aGlz
+CnRyeXt0PXUubi5hKGwuYS5hLmMpCnE9bC5iCmlmKEgub1QocS5hLkhSKHQpKSYmcS5hLmUhPW51bGwp
+e3EuYz1xLmEuS3codCkKcS5iPSExfX1jYXRjaChwKXtzPUguUnUocCkKcj1ILnRzKHApCnE9dS5uLmEo
+bC5hLmEuYykKbz1xLmEKbj1zCm09bC5iCmlmKG89PW51bGw/bj09bnVsbDpvPT09biltLmM9cQplbHNl
+IG0uYz1QLlRsKHMscikKbS5iPSEwfX0sCiRTOjF9ClAuT00ucHJvdG90eXBlPXt9ClAucWgucHJvdG90
+eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7dmFyIHQscyxyPXRoaXMscT17fSxwPW5ldyBQLnZzKCQuWDMsdS5m
+SikKcS5hPTAKdD1ILkxoKHIpCnM9dC5DKCJ+KDEpPyIpLmEobmV3IFAuQjUocSxyKSkKdS5aLmEobmV3
+IFAudU8ocSxwKSkKVy5KRShyLmEsci5iLHMsITEsdC5jKQpyZXR1cm4gcH19ClAuQjUucHJvdG90eXBl
+PXsKJDE6ZnVuY3Rpb24oYSl7SC5MaCh0aGlzLmIpLmMuYShhKTsrK3RoaXMuYS5hfSwKJFM6ZnVuY3Rp
+b24oKXtyZXR1cm4gSC5MaCh0aGlzLmIpLkMoImM4KDEpIil9fQpQLnVPLnByb3RvdHlwZT17CiQwOmZ1
+bmN0aW9uKCl7dGhpcy5iLkhIKHRoaXMuYS5hKX0sCiRTOjB9ClAuTU8ucHJvdG90eXBlPXt9ClAua1Qu
+cHJvdG90eXBlPXt9ClAueEkucHJvdG90eXBlPXt9ClAuQ3cucHJvdG90eXBlPXsKdzpmdW5jdGlvbihh
+KXtyZXR1cm4gSC5Faih0aGlzLmEpfSwKJGlYUzoxLApnSUk6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5i
+fX0KUC5tMC5wcm90b3R5cGU9eyRpSkI6MX0KUC5wSy5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3Zh
+ciB0PUguYih0aGlzLmEpCnQuc3RhY2s9Si5qKHRoaXMuYikKdGhyb3cgdH0sCiRTOjB9ClAuSmkucHJv
+dG90eXBlPXsKYkg6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHE9bnVsbAp1Lk0uYShhKQp0cnl7aWYoQy5O
+VT09PSQuWDMpe2EuJDAoKQpyZXR1cm59UC5UOChxLHEsdGhpcyxhLHUuSCl9Y2F0Y2gocil7dD1ILlJ1
+KHIpCnM9SC50cyhyKQpQLkwyKHEscSx0aGlzLHQsdS5sLmEocykpfX0sCkRsOmZ1bmN0aW9uKGEsYixj
+KXt2YXIgdCxzLHIscT1udWxsCmMuQygifigwKSIpLmEoYSkKYy5hKGIpCnRyeXtpZihDLk5VPT09JC5Y
+Myl7YS4kMShiKQpyZXR1cm59UC55dihxLHEsdGhpcyxhLGIsdS5ILGMpfWNhdGNoKHIpe3Q9SC5SdShy
+KQpzPUgudHMocikKUC5MMihxLHEsdGhpcyx0LHUubC5hKHMpKX19LApSVDpmdW5jdGlvbihhLGIpe3Jl
+dHVybiBuZXcgUC5oaih0aGlzLGIuQygiMCgpIikuYShhKSxiKX0sCkdZOmZ1bmN0aW9uKGEpe3JldHVy
+biBuZXcgUC5WcCh0aGlzLHUuTS5hKGEpKX0sClB5OmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBQLk9S
+KHRoaXMsYi5DKCJ+KDApIikuYShhKSxiKX0sCnE6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbnVsbH0sCnp6
+OmZ1bmN0aW9uKGEsYil7Yi5DKCIwKCkiKS5hKGEpCmlmKCQuWDM9PT1DLk5VKXJldHVybiBhLiQwKCkK
+cmV0dXJuIFAuVDgobnVsbCxudWxsLHRoaXMsYSxiKX0sCmJ2OmZ1bmN0aW9uKGEsYixjLGQpe2MuQygi
+QDwwPiIpLktxKGQpLkMoIjEoMikiKS5hKGEpCmQuYShiKQppZigkLlgzPT09Qy5OVSlyZXR1cm4gYS4k
+MShiKQpyZXR1cm4gUC55dihudWxsLG51bGwsdGhpcyxhLGIsYyxkKX0sCnJwOmZ1bmN0aW9uKGEsYixj
+LGQsZSxmKXtkLkMoIkA8MD4iKS5LcShlKS5LcShmKS5DKCIxKDIsMykiKS5hKGEpCmUuYShiKQpmLmEo
+YykKaWYoJC5YMz09PUMuTlUpcmV0dXJuIGEuJDIoYixjKQpyZXR1cm4gUC5ReChudWxsLG51bGwsdGhp
+cyxhLGIsYyxkLGUsZil9LApMajpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm4gYi5DKCJAPDA+IikuS3Eo
+YykuS3EoZCkuQygiMSgyLDMpIikuYShhKX19ClAuaGoucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXty
+ZXR1cm4gdGhpcy5hLnp6KHRoaXMuYix0aGlzLmMpfSwKJFM6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5j
+LkMoIjAoKSIpfX0KUC5WcC5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmEuYkgo
+dGhpcy5iKX0sCiRTOjF9ClAuT1IucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5j
+CnJldHVybiB0aGlzLmEuRGwodGhpcy5iLHQuYShhKSx0KX0sCiRTOmZ1bmN0aW9uKCl7cmV0dXJuIHRo
+aXMuYy5DKCJ+KDApIil9fQpQLmI2LnByb3RvdHlwZT17CmdrejpmdW5jdGlvbihhKXt2YXIgdD10aGlz
+LHM9bmV3IFAubG0odCx0LnIsSC5MaCh0KS5DKCJsbTwxPiIpKQpzLmM9dC5lCnJldHVybiBzfSwKZ0E6
+ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYX0sCnRnOmZ1bmN0aW9uKGEsYil7dmFyIHQscwppZihiIT09
+Il9fcHJvdG9fXyIpe3Q9dGhpcy5iCmlmKHQ9PW51bGwpcmV0dXJuITEKcmV0dXJuIHUuSi5hKHRbYl0p
+IT1udWxsfWVsc2V7cz10aGlzLlBSKGIpCnJldHVybiBzfX0sClBSOmZ1bmN0aW9uKGEpe3ZhciB0PXRo
+aXMuZAppZih0PT1udWxsKXJldHVybiExCnJldHVybiB0aGlzLkRGKHRbdGhpcy5OKGEpXSxhKT49MH0s
+Cmk6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9dGhpcwpILkxoKHIpLmMuYShiKQppZih0eXBlb2YgYj09
+InN0cmluZyImJmIhPT0iX19wcm90b19fIil7dD1yLmIKcmV0dXJuIHIuUyh0PT1udWxsP3IuYj1QLlQy
+KCk6dCxiKX1lbHNlIGlmKHR5cGVvZiBiPT0ibnVtYmVyIiYmKGImMTA3Mzc0MTgyMyk9PT1iKXtzPXIu
+YwpyZXR1cm4gci5TKHM9PW51bGw/ci5jPVAuVDIoKTpzLGIpfWVsc2UgcmV0dXJuIHIuQjcoYil9LApC
+NzpmdW5jdGlvbihhKXt2YXIgdCxzLHIscT10aGlzCkguTGgocSkuYy5hKGEpCnQ9cS5kCmlmKHQ9PW51
+bGwpdD1xLmQ9UC5UMigpCnM9cS5OKGEpCnI9dFtzXQppZihyPT1udWxsKXRbc109W3EueW8oYSldCmVs
+c2V7aWYocS5ERihyLGEpPj0wKXJldHVybiExCnIucHVzaChxLnlvKGEpKX1yZXR1cm4hMH0sClI6ZnVu
+Y3Rpb24oYSxiKXt2YXIgdD10aGlzCmlmKHR5cGVvZiBiPT0ic3RyaW5nIiYmYiE9PSJfX3Byb3RvX18i
+KXJldHVybiB0LkwodC5iLGIpCmVsc2UgaWYodHlwZW9mIGI9PSJudW1iZXIiJiYoYiYxMDczNzQxODIz
+KT09PWIpcmV0dXJuIHQuTCh0LmMsYikKZWxzZSByZXR1cm4gdC5xZyhiKX0sCnFnOmZ1bmN0aW9uKGEp
+e3ZhciB0LHMscixxLHA9dGhpcyxvPXAuZAppZihvPT1udWxsKXJldHVybiExCnQ9cC5OKGEpCnM9b1t0
+XQpyPXAuREYocyxhKQppZihyPDApcmV0dXJuITEKcT1zLnNwbGljZShyLDEpWzBdCmlmKDA9PT1zLmxl
+bmd0aClkZWxldGUgb1t0XQpwLkdTKHEpCnJldHVybiEwfSwKUzpmdW5jdGlvbihhLGIpe0guTGgodGhp
+cykuYy5hKGIpCmlmKHUuSi5hKGFbYl0pIT1udWxsKXJldHVybiExCmFbYl09dGhpcy55byhiKQpyZXR1
+cm4hMH0sCkw6ZnVuY3Rpb24oYSxiKXt2YXIgdAppZihhPT1udWxsKXJldHVybiExCnQ9dS5KLmEoYVti
+XSkKaWYodD09bnVsbClyZXR1cm4hMQp0aGlzLkdTKHQpCmRlbGV0ZSBhW2JdCnJldHVybiEwfSwKWDpm
+dW5jdGlvbigpe3RoaXMucj0xMDczNzQxODIzJnRoaXMucisxfSwKeW86ZnVuY3Rpb24oYSl7dmFyIHQs
+cz10aGlzLHI9bmV3IFAuYm4oSC5MaChzKS5jLmEoYSkpCmlmKHMuZT09bnVsbClzLmU9cy5mPXIKZWxz
+ZXt0PXMuZgp0LnRvU3RyaW5nCnIuYz10CnMuZj10LmI9cn0rK3MuYQpzLlgoKQpyZXR1cm4gcn0sCkdT
+OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMscz1hLmMscj1hLmIKaWYocz09bnVsbCl0LmU9cgplbHNlIHMu
+Yj1yCmlmKHI9PW51bGwpdC5mPXMKZWxzZSByLmM9czstLXQuYQp0LlgoKX0sCk46ZnVuY3Rpb24oYSl7
+cmV0dXJuIEouaGYoYSkmMTA3Mzc0MTgyM30sCkRGOmZ1bmN0aW9uKGEsYil7dmFyIHQscwppZihhPT1u
+dWxsKXJldHVybi0xCnQ9YS5sZW5ndGgKZm9yKHM9MDtzPHQ7KytzKWlmKEouUk0oYVtzXS5hLGIpKXJl
+dHVybiBzCnJldHVybi0xfX0KUC5ibi5wcm90b3R5cGU9e30KUC5sbS5wcm90b3R5cGU9ewpnbDpmdW5j
+dGlvbigpe3JldHVybiB0aGlzLmR9LApGOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcyxzPXQuYyxyPXQuYQpp
+Zih0LmIhPT1yLnIpdGhyb3cgSC5iKFAuYTQocikpCmVsc2UgaWYocz09bnVsbCl7dC5zaihudWxsKQpy
+ZXR1cm4hMX1lbHNle3Quc2oodC4kdGkuQygiMT8iKS5hKHMuYSkpCnQuYz1zLmIKcmV0dXJuITB9fSwK
+c2o6ZnVuY3Rpb24oYSl7dGhpcy5kPXRoaXMuJHRpLkMoIjE/IikuYShhKX0sCiRpQW46MX0KUC5tVy5w
+cm90b3R5cGU9e30KUC5MVS5wcm90b3R5cGU9eyRpYlE6MSwkaWNYOjEsJGl6TToxfQpQLmxELnByb3Rv
+dHlwZT17CmdrejpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEguYTcoYSx0aGlzLmdBKGEpLEgueihhKS5D
+KCJhNzxsRC5FPiIpKX0sCkU6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5xKGEsYil9LApLOmZ1bmN0
+aW9uKGEsYil7dmFyIHQscwpILnooYSkuQygifihsRC5FKSIpLmEoYikKdD10aGlzLmdBKGEpCmZvcihz
+PTA7czx0Oysrcyl7Yi4kMSh0aGlzLnEoYSxzKSkKaWYodCE9PXRoaXMuZ0EoYSkpdGhyb3cgSC5iKFAu
+YTQoYSkpfX0sCkUyOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1ILnooYSkKcmV0dXJuIG5ldyBILmxKKGEs
+dC5LcShjKS5DKCIxKGxELkUpIikuYShiKSx0LkMoIkA8bEQuRT4iKS5LcShjKS5DKCJsSjwxLDI+Iikp
+fSwKZHU6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQKSC56KGEpLkMoImxELkU/IikuYShkKQpQLmpCKGIs
+Yyx0aGlzLmdBKGEpKQpmb3IodD1iO3Q8YzsrK3QpdGhpcy5ZKGEsdCxkKX0sCnc6ZnVuY3Rpb24oYSl7
+cmV0dXJuIFAuV0UoYSwiWyIsIl0iKX19ClAuaWwucHJvdG90eXBlPXt9ClAucmEucHJvdG90eXBlPXsK
+JDI6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzPXRoaXMuYQppZighcy5hKXRoaXMuYi5hKz0iLCAiCnMuYT0h
+MQpzPXRoaXMuYgp0PXMuYSs9SC5FaihhKQpzLmE9dCsiOiAiCnMuYSs9SC5FaihiKX0sCiRTOjQzfQpQ
+LllrLnByb3RvdHlwZT17Cks6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzCkguTGgodGhpcykuQygifihZay5L
+LFlrLlYpIikuYShiKQpmb3IodD1KLklUKHRoaXMuZ1YoKSk7dC5GKCk7KXtzPXQuZ2woKQpiLiQyKHMs
+dGhpcy5xKDAscykpfX0sCmdQdTpmdW5jdGlvbihhKXtyZXR1cm4gSi5NMSh0aGlzLmdWKCksbmV3IFAu
+eVEodGhpcyksSC5MaCh0aGlzKS5DKCJOMzxZay5LLFlrLlY+IikpfSwKeDQ6ZnVuY3Rpb24oYSl7cmV0
+dXJuIEouemwodGhpcy5nVigpLGEpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIEouSG0odGhpcy5nVigp
+KX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFAubk8odGhpcyl9LAokaVowOjF9ClAueVEucHJvdG90eXBl
+PXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hLHM9SC5MaCh0KQpzLkMoIllrLksiKS5hKGEpCnJl
+dHVybiBuZXcgUC5OMyhhLHQucSgwLGEpLHMuQygiQDxZay5LPiIpLktxKHMuQygiWWsuViIpKS5DKCJO
+MzwxLDI+IikpfSwKJFM6ZnVuY3Rpb24oKXtyZXR1cm4gSC5MaCh0aGlzLmEpLkMoIk4zPFlrLkssWWsu
+Vj4oWWsuSykiKX19ClAuS1AucHJvdG90eXBlPXsKWTpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9SC5MaCh0
+aGlzKQp0LmMuYShiKQp0LlFbMV0uYShjKQp0aHJvdyBILmIoUC5MNCgiQ2Fubm90IG1vZGlmeSB1bm1v
+ZGlmaWFibGUgbWFwIikpfX0KUC5Qbi5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRo
+aXMuYS5xKDAsYil9LApZOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1ILkxoKHRoaXMpCnRoaXMuYS5ZKDAs
+dC5jLmEoYiksdC5RWzFdLmEoYykpfSwKeDQ6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS54NChhKX0s
+Cks6ZnVuY3Rpb24oYSxiKXt0aGlzLmEuSygwLEguTGgodGhpcykuQygifigxLDIpIikuYShiKSl9LApn
+QTpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEKcmV0dXJuIHQuZ0EodCl9LAp3OmZ1bmN0aW9uKGEpe3Jl
+dHVybiBKLmoodGhpcy5hKX0sCmdQdTpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEKcmV0dXJuIHQuZ1B1
+KHQpfSwKJGlaMDoxfQpQLkdqLnByb3RvdHlwZT17fQpQLk1hLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24o
+YSl7cmV0dXJuIFAuV0UodGhpcywieyIsIn0iKX19ClAuVmoucHJvdG90eXBlPXskaWJROjEsJGljWDox
+LCRpeHU6MX0KUC5Ydi5wcm90b3R5cGU9ewpGVjpmdW5jdGlvbihhLGIpe3ZhciB0CmZvcih0PUouSVQo
+SC5MaCh0aGlzKS5DKCJjWDwxPiIpLmEoYikpO3QuRigpOyl0aGlzLmkoMCx0LmdsKCkpfSwKdzpmdW5j
+dGlvbihhKXtyZXR1cm4gUC5XRSh0aGlzLCJ7IiwifSIpfSwKelY6ZnVuY3Rpb24oYSxiKXt2YXIgdCxz
+PVAucmoodGhpcyx0aGlzLnIsSC5MaCh0aGlzKS5jKQppZighcy5GKCkpcmV0dXJuIiIKaWYoYj09PSIi
+KXt0PSIiCmRvIHQrPUguRWoocy5kKQp3aGlsZShzLkYoKSl9ZWxzZXt0PSIiK0guRWoocy5kKQpmb3Io
+O3MuRigpOyl0PXQrYitILkVqKHMuZCl9cmV0dXJuIHQuY2hhckNvZGVBdCgwKT09MD90OnR9LAokaWJR
+OjEsCiRpY1g6MSwKJGl4dToxfQpQLm5ZLnByb3RvdHlwZT17fQpQLldZLnByb3RvdHlwZT17fQpQLlJV
+LnByb3RvdHlwZT17fQpQLnV3LnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzPXRoaXMu
+YgppZihzPT1udWxsKXJldHVybiB0aGlzLmMucSgwLGIpCmVsc2UgaWYodHlwZW9mIGIhPSJzdHJpbmci
+KXJldHVybiBudWxsCmVsc2V7dD1zW2JdCnJldHVybiB0eXBlb2YgdD09InVuZGVmaW5lZCI/dGhpcy5m
+YihiKTp0fX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmI9PW51bGw/dGhpcy5jLmE6dGhpcy5D
+ZigpLmxlbmd0aH0sCmdWOmZ1bmN0aW9uKCl7aWYodGhpcy5iPT1udWxsKXt2YXIgdD10aGlzLmMKcmV0
+dXJuIG5ldyBILmk1KHQsSC5MaCh0KS5DKCJpNTwxPiIpKX1yZXR1cm4gbmV3IFAuaTgodGhpcyl9LApZ
+OmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHI9dGhpcwppZihyLmI9PW51bGwpci5jLlkoMCxiLGMpCmVs
+c2UgaWYoci54NChiKSl7dD1yLmIKdFtiXT1jCnM9ci5hCmlmKHM9PW51bGw/dCE9bnVsbDpzIT09dClz
+W2JdPW51bGx9ZWxzZSByLlhLKCkuWSgwLGIsYyl9LAp4NDpmdW5jdGlvbihhKXtpZih0aGlzLmI9PW51
+bGwpcmV0dXJuIHRoaXMuYy54NChhKQpyZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0
+eS5jYWxsKHRoaXMuYSxhKX0sCks6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwPXRoaXMKdS5jQS5h
+KGIpCmlmKHAuYj09bnVsbClyZXR1cm4gcC5jLksoMCxiKQp0PXAuQ2YoKQpmb3Iocz0wO3M8dC5sZW5n
+dGg7KytzKXtyPXRbc10KcT1wLmJbcl0KaWYodHlwZW9mIHE9PSJ1bmRlZmluZWQiKXtxPVAuUWUocC5h
+W3JdKQpwLmJbcl09cX1iLiQyKHIscSkKaWYodCE9PXAuYyl0aHJvdyBILmIoUC5hNChwKSl9fSwKQ2Y6
+ZnVuY3Rpb24oKXt2YXIgdD11LmJNLmEodGhpcy5jKQppZih0PT1udWxsKXQ9dGhpcy5jPUguVk0oT2Jq
+ZWN0LmtleXModGhpcy5hKSx1LnMpCnJldHVybiB0fSwKWEs6ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxw
+LG89dGhpcwppZihvLmI9PW51bGwpcmV0dXJuIG8uYwp0PVAuRmwodS5OLHUueikKcz1vLkNmKCkKZm9y
+KHI9MDtxPXMubGVuZ3RoLHI8cTsrK3Ipe3A9c1tyXQp0LlkoMCxwLG8ucSgwLHApKX1pZihxPT09MClD
+Lk5tLmkocywiIikKZWxzZSBDLk5tLnNBKHMsMCkKby5hPW8uYj1udWxsCnJldHVybiBvLmM9dH0sCmZi
+OmZ1bmN0aW9uKGEpe3ZhciB0CmlmKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwo
+dGhpcy5hLGEpKXJldHVybiBudWxsCnQ9UC5RZSh0aGlzLmFbYV0pCnJldHVybiB0aGlzLmJbYV09dH19
+ClAuaTgucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCnJldHVybiB0LmdBKHQp
+fSwKRTpmdW5jdGlvbihhLGIpe3ZhciB0PXRoaXMuYQppZih0LmI9PW51bGwpdD10LmdWKCkuRSgwLGIp
+CmVsc2V7dD10LkNmKCkKaWYoYjwwfHxiPj10Lmxlbmd0aClyZXR1cm4gSC5PSCh0LGIpCnQ9dFtiXX1y
+ZXR1cm4gdH0sCmdrejpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEKaWYodC5iPT1udWxsKXt0PXQuZ1Yo
+KQp0PXQuZ2t6KHQpfWVsc2V7dD10LkNmKCkKdD1uZXcgSi5tMSh0LHQubGVuZ3RoLEgudDYodCkuQygi
+bTE8MT4iKSl9cmV0dXJuIHR9LAp0ZzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmEueDQoYil9fQpQ
+LnBnLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7dmFyIHQscwp0cnl7dD1uZXcgVGV4dERlY29kZXIo
+InV0Zi04Iix7ZmF0YWw6dHJ1ZX0pCnJldHVybiB0fWNhdGNoKHMpe0guUnUocyl9cmV0dXJuIG51bGx9
+LAokUzo0NX0KUC5DVi5wcm90b3R5cGU9ewp5cjpmdW5jdGlvbihhLGEwLGExKXt2YXIgdCxzLHIscSxw
+LG8sbixtLGwsayxqLGksaCxnLGYsZSxkLGMsYj0iSW52YWxpZCBiYXNlNjQgZW5jb2RpbmcgbGVuZ3Ro
+ICIKYTE9UC5qQihhMCxhMSxhLmxlbmd0aCkKdD0kLlY3KCkKZm9yKHM9YTAscj1zLHE9bnVsbCxwPS0x
+LG89LTEsbj0wO3M8YTE7cz1tKXttPXMrMQpsPUMueEIuVyhhLHMpCmlmKGw9PT0zNyl7az1tKzIKaWYo
+azw9YTEpe2o9SC5vbyhDLnhCLlcoYSxtKSkKaT1ILm9vKEMueEIuVyhhLG0rMSkpCmg9aioxNitpLShp
+JjI1NikKaWYoaD09PTM3KWg9LTEKbT1rfWVsc2UgaD0tMX1lbHNlIGg9bAppZigwPD1oJiZoPD0xMjcp
+e2lmKGg8MHx8aD49dC5sZW5ndGgpcmV0dXJuIEguT0godCxoKQpnPXRbaF0KaWYoZz49MCl7aD1DLnhC
+Lm0oIkFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIz
+NDU2Nzg5Ky8iLGcpCmlmKGg9PT1sKWNvbnRpbnVlCmw9aH1lbHNle2lmKGc9PT0tMSl7aWYocDwwKXtm
+PXE9PW51bGw/bnVsbDpxLmEubGVuZ3RoCmlmKGY9PW51bGwpZj0wCnA9Zisocy1yKQpvPXN9KytuCmlm
+KGw9PT02MSljb250aW51ZX1sPWh9aWYoZyE9PS0yKXtpZihxPT1udWxsKXtxPW5ldyBQLlJuKCIiKQpm
+PXF9ZWxzZSBmPXEKZi5hKz1DLnhCLk5qKGEscixzKQpmLmErPUguTHcobCkKcj1tCmNvbnRpbnVlfX10
+aHJvdyBILmIoUC5ycigiSW52YWxpZCBiYXNlNjQgZGF0YSIsYSxzKSl9aWYocSE9bnVsbCl7Zj1xLmEr
+PUMueEIuTmooYSxyLGExKQplPWYubGVuZ3RoCmlmKHA+PTApUC54TShhLG8sYTEscCxuLGUpCmVsc2V7
+ZD1DLmpuLnpZKGUtMSw0KSsxCmlmKGQ9PT0xKXRocm93IEguYihQLnJyKGIsYSxhMSkpCmZvcig7ZDw0
+Oyl7Zis9Ij0iCnEuYT1mOysrZH19Zj1xLmEKcmV0dXJuIEMueEIuaTcoYSxhMCxhMSxmLmNoYXJDb2Rl
+QXQoMCk9PTA/ZjpmKX1jPWExLWEwCmlmKHA+PTApUC54TShhLG8sYTEscCxuLGMpCmVsc2V7ZD1DLmpu
+LnpZKGMsNCkKaWYoZD09PTEpdGhyb3cgSC5iKFAucnIoYixhLGExKSkKaWYoZD4xKWE9Qy54Qi5pNyhh
+LGExLGExLGQ9PT0yPyI9PSI6Ij0iKX1yZXR1cm4gYX19ClAuVTgucHJvdG90eXBlPXt9ClAuVWsucHJv
+dG90eXBlPXt9ClAud0kucHJvdG90eXBlPXt9ClAuWmkucHJvdG90eXBlPXt9ClAuYnkucHJvdG90eXBl
+PXsKcFc6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0CnUuZlYuYShjKQp0PVAuQlMoYix0aGlzLmdIZSgpLmEp
+CnJldHVybiB0fSwKZ0hlOmZ1bmN0aW9uKCl7cmV0dXJuIEMuQTN9fQpQLk14LnByb3RvdHlwZT17fQpQ
+LnU1LnByb3RvdHlwZT17CmdaRTpmdW5jdGlvbigpe3JldHVybiBDLlFrfX0KUC5FMy5wcm90b3R5cGU9
+ewpXSjpmdW5jdGlvbihhKXt2YXIgdCxzLHI9UC5qQigwLG51bGwsYS5sZW5ndGgpLHE9ci0wCmlmKHE9
+PT0wKXJldHVybiBuZXcgVWludDhBcnJheSgwKQp0PW5ldyBVaW50OEFycmF5KHEqMykKcz1uZXcgUC5S
+dyh0KQppZihzLkd4KGEsMCxyKSE9PXIpcy5PNihKLmE2KGEsci0xKSwwKQpyZXR1cm4gbmV3IFVpbnQ4
+QXJyYXkodC5zdWJhcnJheSgwLEguck0oMCxzLmIsdC5sZW5ndGgpKSl9fQpQLlJ3LnByb3RvdHlwZT17
+Ck82OmZ1bmN0aW9uKGEsYil7dmFyIHQscz10aGlzLHI9cy5jLHE9cy5iLHA9cSsxLG89ci5sZW5ndGgK
+aWYoKGImNjQ1MTIpPT09NTYzMjApe3Q9NjU1MzYrKChhJjEwMjMpPDwxMCl8YiYxMDIzCnMuYj1wCmlm
+KHE+PW8pcmV0dXJuIEguT0gocixxKQpyW3FdPTI0MHx0Pj4+MTgKcT1zLmI9cCsxCmlmKHA+PW8pcmV0
+dXJuIEguT0gocixwKQpyW3BdPTEyOHx0Pj4+MTImNjMKcD1zLmI9cSsxCmlmKHE+PW8pcmV0dXJuIEgu
+T0gocixxKQpyW3FdPTEyOHx0Pj4+NiY2MwpzLmI9cCsxCmlmKHA+PW8pcmV0dXJuIEguT0gocixwKQpy
+W3BdPTEyOHx0JjYzCnJldHVybiEwfWVsc2V7cy5iPXAKaWYocT49bylyZXR1cm4gSC5PSChyLHEpCnJb
+cV09MjI0fGE+Pj4xMgpxPXMuYj1wKzEKaWYocD49bylyZXR1cm4gSC5PSChyLHApCnJbcF09MTI4fGE+
+Pj42JjYzCnMuYj1xKzEKaWYocT49bylyZXR1cm4gSC5PSChyLHEpCnJbcV09MTI4fGEmNjMKcmV0dXJu
+ITF9fSwKR3g6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxLHAsbyxuLG09dGhpcwppZihiIT09YyYm
+KEMueEIubShhLGMtMSkmNjQ1MTIpPT09NTUyOTYpLS1jCmZvcih0PW0uYyxzPXQubGVuZ3RoLHI9Yjty
+PGM7KytyKXtxPUMueEIuVyhhLHIpCmlmKHE8PTEyNyl7cD1tLmIKaWYocD49cylicmVhawptLmI9cCsx
+CnRbcF09cX1lbHNlIGlmKChxJjY0NTEyKT09PTU1Mjk2KXtpZihtLmIrMz49cylicmVhawpvPXIrMQpp
+ZihtLk82KHEsQy54Qi5XKGEsbykpKXI9b31lbHNlIGlmKHE8PTIwNDcpe3A9bS5iCm49cCsxCmlmKG4+
+PXMpYnJlYWsKbS5iPW4KaWYocD49cylyZXR1cm4gSC5PSCh0LHApCnRbcF09MTkyfHE+Pj42Cm0uYj1u
+KzEKdFtuXT0xMjh8cSY2M31lbHNle3A9bS5iCmlmKHArMj49cylicmVhawpuPW0uYj1wKzEKaWYocD49
+cylyZXR1cm4gSC5PSCh0LHApCnRbcF09MjI0fHE+Pj4xMgpwPW0uYj1uKzEKaWYobj49cylyZXR1cm4g
+SC5PSCh0LG4pCnRbbl09MTI4fHE+Pj42JjYzCm0uYj1wKzEKaWYocD49cylyZXR1cm4gSC5PSCh0LHAp
+CnRbcF09MTI4fHEmNjN9fXJldHVybiByfX0KUC5HWS5wcm90b3R5cGU9ewpXSjpmdW5jdGlvbihhKXt2
+YXIgdCxzLHIscSxwLG8sbixtLGwKdS5MLmEoYSkKdD1QLmt5KCExLGEsMCxudWxsKQppZih0IT1udWxs
+KXJldHVybiB0CnM9UC5qQigwLG51bGwsSi5IbShhKSkKcj1QLmNQKGEsMCxzKQppZihyPjApe3E9UC5I
+TShhLDAscikKaWYocj09PXMpcmV0dXJuIHEKcD1uZXcgUC5SbihxKQpvPXIKbj0hMX1lbHNle3A9bmV3
+IFAuUm4oIiIpCm89MApuPSEwfW09bmV3IFAuYnooITEscCkKbS5jPW4KbS5NRShhLG8scykKdS5lZy5h
+KGEpCmlmKG0uZT4wKXtILnZoKFAucnIoIlVuZmluaXNoZWQgVVRGLTggb2N0ZXQgc2VxdWVuY2UiLGEs
+cykpCnAuYSs9SC5Mdyg2NTUzMykKbS5mPW0uZT1tLmQ9MH1sPXAuYQpyZXR1cm4gbC5jaGFyQ29kZUF0
+KDApPT0wP2w6bH19ClAuYnoucHJvdG90eXBlPXsKTUU6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixx
+LHAsbyxuLG0sbCxrLGosaSxoPXRoaXMsZz0iQmFkIFVURi04IGVuY29kaW5nIDB4Igp1LkwuYShhKQp0
+PWguZApzPWguZQpyPWguZgpoLmY9aC5lPWguZD0wCiRsYWJlbDAkMDpmb3IocT1KLlU2KGEpLHA9aC5i
+LG89YjshMDtvPWopeyRsYWJlbDEkMTppZihzPjApe2Rve2lmKG89PT1jKWJyZWFrICRsYWJlbDAkMApu
+PXEucShhLG8pCmlmKHR5cGVvZiBuIT09Im51bWJlciIpcmV0dXJuIG4uek0oKQppZigobiYxOTIpIT09
+MTI4KXttPVAucnIoZytDLmpuLldaKG4sMTYpLGEsbykKdGhyb3cgSC5iKG0pfWVsc2V7dD0odDw8Nnxu
+JjYzKT4+PjA7LS1zOysrb319d2hpbGUocz4wKQptPXItMQppZihtPDB8fG0+PTQpcmV0dXJuIEguT0go
+Qy5HYixtKQppZih0PD1DLkdiW21dKXttPVAucnIoIk92ZXJsb25nIGVuY29kaW5nIG9mIDB4IitDLmpu
+LldaKHQsMTYpLGEsby1yLTEpCnRocm93IEguYihtKX1pZih0PjExMTQxMTEpe209UC5ycigiQ2hhcmFj
+dGVyIG91dHNpZGUgdmFsaWQgVW5pY29kZSByYW5nZTogMHgiK0Muam4uV1oodCwxNiksYSxvLXItMSkK
+dGhyb3cgSC5iKG0pfWlmKCFoLmN8fHQhPT02NTI3OSlwLmErPUguTHcodCkKaC5jPSExfWZvcihtPW88
+YzttOyl7bD1QLmNQKGEsbyxjKQppZihsPjApe2guYz0hMQprPW8rbApwLmErPVAuSE0oYSxvLGspCmlm
+KGs9PT1jKWJyZWFrfWVsc2Ugaz1vCmo9aysxCm49cS5xKGEsaykKaWYodHlwZW9mIG4hPT0ibnVtYmVy
+IilyZXR1cm4gbi5KKCkKaWYobjwwKXtpPVAucnIoIk5lZ2F0aXZlIFVURi04IGNvZGUgdW5pdDogLTB4
+IitDLmpuLldaKC1uLDE2KSxhLGotMSkKdGhyb3cgSC5iKGkpfWVsc2V7aWYoKG4mMjI0KT09PTE5Mil7
+dD1uJjMxCnM9MQpyPTEKY29udGludWUgJGxhYmVsMCQwfWlmKChuJjI0MCk9PT0yMjQpe3Q9biYxNQpz
+PTIKcj0yCmNvbnRpbnVlICRsYWJlbDAkMH1pZigobiYyNDgpPT09MjQwJiZuPDI0NSl7dD1uJjcKcz0z
+CnI9Mwpjb250aW51ZSAkbGFiZWwwJDB9aT1QLnJyKGcrQy5qbi5XWihuLDE2KSxhLGotMSkKdGhyb3cg
+SC5iKGkpfX1icmVhayAkbGFiZWwwJDB9aWYocz4wKXtoLmQ9dApoLmU9cwpoLmY9cn19fQpQLldGLnBy
+b3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyCnUuZm8uYShhKQp0PXRoaXMuYgpzPXRo
+aXMuYQp0LmErPXMuYQpyPXQuYSs9SC5FaihhLmEpCnQuYT1yKyI6ICIKdC5hKz1QLnAoYikKcy5hPSIs
+ICJ9LAokUzo0Nn0KUC5hMi5wcm90b3R5cGU9e30KUC5pUC5wcm90b3R5cGU9ewpETjpmdW5jdGlvbihh
+LGIpe2lmKGI9PW51bGwpcmV0dXJuITEKcmV0dXJuIGIgaW5zdGFuY2VvZiBQLmlQJiZ0aGlzLmE9PT1i
+LmEmJiEwfSwKZ2lPOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYQpyZXR1cm4odF5DLmpuLndHKHQsMzAp
+KSYxMDczNzQxODIzfSwKdzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLHM9UC5HcShILnRKKHQpKSxyPVAu
+aDAoSC5OUyh0KSkscT1QLmgwKEguakEodCkpLHA9UC5oMChILklYKHQpKSxvPVAuaDAoSC5jaCh0KSks
+bj1QLmgwKEguSmQodCkpLG09UC5WeChILm8xKHQpKSxsPXMrIi0iK3IrIi0iK3ErIiAiK3ArIjoiK28r
+IjoiK24rIi4iK20KcmV0dXJuIGx9fQpQLkNQLnByb3RvdHlwZT17fQpQLlhTLnByb3RvdHlwZT17CmdJ
+STpmdW5jdGlvbigpe3JldHVybiBILnRzKHRoaXMuJHRocm93bkpzRXJyb3IpfX0KUC5DNi5wcm90b3R5
+cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYQppZih0IT1udWxsKXJldHVybiJBc3NlcnRpb24g
+ZmFpbGVkOiAiK1AucCh0KQpyZXR1cm4iQXNzZXJ0aW9uIGZhaWxlZCJ9fQpQLm4ucHJvdG90eXBlPXsK
+dzpmdW5jdGlvbihhKXtyZXR1cm4iVGhyb3cgb2YgbnVsbC4ifX0KUC51LnByb3RvdHlwZT17CmdaOmZ1
+bmN0aW9uKCl7cmV0dXJuIkludmFsaWQgYXJndW1lbnQiKyghdGhpcy5hPyIocykiOiIiKX0sCmd1OmZ1
+bmN0aW9uKCl7cmV0dXJuIiJ9LAp3OmZ1bmN0aW9uKGEpe3ZhciB0LHMscj10aGlzLHE9ci5jLHA9cT09
+bnVsbD8iIjoiICgiK3ErIikiLG89ci5kLG49bz09bnVsbD8iIjoiOiAiK0guRWoobyksbT1yLmdaKCkr
+cCtuCmlmKCFyLmEpcmV0dXJuIG0KdD1yLmd1KCkKcz1QLnAoci5iKQpyZXR1cm4gbSt0KyI6ICIrc319
+ClAuYkoucHJvdG90eXBlPXsKZ1o6ZnVuY3Rpb24oKXtyZXR1cm4iUmFuZ2VFcnJvciJ9LApndTpmdW5j
+dGlvbigpe3ZhciB0LHM9dGhpcy5lLHI9dGhpcy5mCmlmKHM9PW51bGwpdD1yIT1udWxsPyI6IE5vdCBs
+ZXNzIHRoYW4gb3IgZXF1YWwgdG8gIitILkVqKHIpOiIiCmVsc2UgaWYocj09bnVsbCl0PSI6IE5vdCBn
+cmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gIitILkVqKHMpCmVsc2UgaWYocj5zKXQ9IjogTm90IGluIHJh
+bmdlICIrSC5FaihzKSsiLi4iK0guRWoocikrIiwgaW5jbHVzaXZlIgplbHNlIHQ9cjxzPyI6IFZhbGlk
+IHZhbHVlIHJhbmdlIGlzIGVtcHR5IjoiOiBPbmx5IHZhbGlkIHZhbHVlIGlzICIrSC5FaihzKQpyZXR1
+cm4gdH19ClAuZVkucHJvdG90eXBlPXsKZ1o6ZnVuY3Rpb24oKXtyZXR1cm4iUmFuZ2VFcnJvciJ9LApn
+dTpmdW5jdGlvbigpe3ZhciB0LHM9SC51UCh0aGlzLmIpCmlmKHR5cGVvZiBzIT09Im51bWJlciIpcmV0
+dXJuIHMuSigpCmlmKHM8MClyZXR1cm4iOiBpbmRleCBtdXN0IG5vdCBiZSBuZWdhdGl2ZSIKdD10aGlz
+LmYKaWYodD09PTApcmV0dXJuIjogbm8gaW5kaWNlcyBhcmUgdmFsaWQiCnJldHVybiI6IGluZGV4IHNo
+b3VsZCBiZSBsZXNzIHRoYW4gIit0fSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZn19ClAubXAu
+cHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixtLGw9dGhpcyxrPXt9LGo9
+bmV3IFAuUm4oIiIpCmsuYT0iIgp0PWwuYwpmb3Iocz10Lmxlbmd0aCxyPTAscT0iIixwPSIiO3I8czsr
+K3IscD0iLCAiKXtvPXRbcl0Kai5hPXErcApxPWouYSs9UC5wKG8pCmsuYT0iLCAifWwuZC5LKDAsbmV3
+IFAuV0YoayxqKSkKbj1QLnAobC5hKQptPWoudygwKQpzPSJOb1N1Y2hNZXRob2RFcnJvcjogbWV0aG9k
+IG5vdCBmb3VuZDogJyIrSC5FaihsLmIuYSkrIidcblJlY2VpdmVyOiAiK24rIlxuQXJndW1lbnRzOiBb
+IittKyJdIgpyZXR1cm4gc319ClAudWIucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iVW5z
+dXBwb3J0ZWQgb3BlcmF0aW9uOiAiK3RoaXMuYX19ClAuZHMucHJvdG90eXBlPXsKdzpmdW5jdGlvbihh
+KXt2YXIgdD10aGlzLmEKcmV0dXJuIHQhPW51bGw/IlVuaW1wbGVtZW50ZWRFcnJvcjogIit0OiJVbmlt
+cGxlbWVudGVkRXJyb3IifX0KUC5sai5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJCYWQg
+c3RhdGU6ICIrdGhpcy5hfX0KUC5VVi5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMu
+YQppZih0PT1udWxsKXJldHVybiJDb25jdXJyZW50IG1vZGlmaWNhdGlvbiBkdXJpbmcgaXRlcmF0aW9u
+LiIKcmV0dXJuIkNvbmN1cnJlbnQgbW9kaWZpY2F0aW9uIGR1cmluZyBpdGVyYXRpb246ICIrUC5wKHQp
+KyIuIn19ClAuazUucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iT3V0IG9mIE1lbW9yeSJ9
+LApnSUk6ZnVuY3Rpb24oKXtyZXR1cm4gbnVsbH0sCiRpWFM6MX0KUC5LWS5wcm90b3R5cGU9ewp3OmZ1
+bmN0aW9uKGEpe3JldHVybiJTdGFjayBPdmVyZmxvdyJ9LApnSUk6ZnVuY3Rpb24oKXtyZXR1cm4gbnVs
+bH0sCiRpWFM6MX0KUC5jLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCnJldHVy
+biB0PT1udWxsPyJSZWFkaW5nIHN0YXRpYyB2YXJpYWJsZSBkdXJpbmcgaXRzIGluaXRpYWxpemF0aW9u
+IjoiUmVhZGluZyBzdGF0aWMgdmFyaWFibGUgJyIrdCsiJyBkdXJpbmcgaXRzIGluaXRpYWxpemF0aW9u
+In19ClAuQ0QucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iRXhjZXB0aW9uOiAiK3RoaXMu
+YX19ClAuYUUucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxq
+LGksaD10aGlzLmEsZz1oIT1udWxsJiYiIiE9PWg/IkZvcm1hdEV4Y2VwdGlvbjogIitILkVqKGgpOiJG
+b3JtYXRFeGNlcHRpb24iLGY9dGhpcy5jLGU9dGhpcy5iCmlmKHR5cGVvZiBlPT0ic3RyaW5nIil7aWYo
+ZiE9bnVsbCl0PWY8MHx8Zj5lLmxlbmd0aAplbHNlIHQ9ITEKaWYodClmPW51bGwKaWYoZj09bnVsbCl7
+aWYoZS5sZW5ndGg+NzgpZT1DLnhCLk5qKGUsMCw3NSkrIi4uLiIKcmV0dXJuIGcrIlxuIitlfWZvcihz
+PTEscj0wLHE9ITEscD0wO3A8ZjsrK3Ape289Qy54Qi5XKGUscCkKaWYobz09PTEwKXtpZihyIT09cHx8
+IXEpKytzCnI9cCsxCnE9ITF9ZWxzZSBpZihvPT09MTMpeysrcwpyPXArMQpxPSEwfX1nPXM+MT9nKygi
+IChhdCBsaW5lICIrcysiLCBjaGFyYWN0ZXIgIisoZi1yKzEpKyIpXG4iKTpnKygiIChhdCBjaGFyYWN0
+ZXIgIisoZisxKSsiKVxuIikKbj1lLmxlbmd0aApmb3IocD1mO3A8bjsrK3Ape289Qy54Qi5tKGUscCkK
+aWYobz09PTEwfHxvPT09MTMpe249cApicmVha319aWYobi1yPjc4KWlmKGYtcjw3NSl7bT1yKzc1Cmw9
+cgprPSIiCmo9Ii4uLiJ9ZWxzZXtpZihuLWY8NzUpe2w9bi03NQptPW4Kaj0iIn1lbHNle2w9Zi0zNgpt
+PWYrMzYKaj0iLi4uIn1rPSIuLi4ifWVsc2V7bT1uCmw9cgprPSIiCmo9IiJ9aT1DLnhCLk5qKGUsbCxt
+KQpyZXR1cm4gZytrK2kraisiXG4iK0MueEIuSXgoIiAiLGYtbCtrLmxlbmd0aCkrIl5cbiJ9ZWxzZSBy
+ZXR1cm4gZiE9bnVsbD9nKygiIChhdCBvZmZzZXQgIitILkVqKGYpKyIpIik6Z319ClAuRUgucHJvdG90
+eXBlPXt9ClAuSWYucHJvdG90eXBlPXt9ClAuY1gucHJvdG90eXBlPXsKRTI6ZnVuY3Rpb24oYSxiLGMp
+e3ZhciB0PUguTGgodGhpcykKcmV0dXJuIEguSzEodGhpcyx0LktxKGMpLkMoIjEoY1guRSkiKS5hKGIp
+LHQuQygiY1guRSIpLGMpfSwKZXY6ZnVuY3Rpb24oYSxiKXt2YXIgdD1ILkxoKHRoaXMpCnJldHVybiBu
+ZXcgSC5VNSh0aGlzLHQuQygiYTIoY1guRSkiKS5hKGIpLHQuQygiVTU8Y1guRT4iKSl9LApnQTpmdW5j
+dGlvbihhKXt2YXIgdCxzPXRoaXMuZ2t6KHRoaXMpCmZvcih0PTA7cy5GKCk7KSsrdApyZXR1cm4gdH0s
+CmdsMDpmdW5jdGlvbihhKXtyZXR1cm4hdGhpcy5na3oodGhpcykuRigpfSwKZ3I4OmZ1bmN0aW9uKGEp
+e3ZhciB0LHM9dGhpcy5na3oodGhpcykKaWYoIXMuRigpKXRocm93IEguYihILldwKCkpCnQ9cy5nbCgp
+CmlmKHMuRigpKXRocm93IEguYihILmRVKCkpCnJldHVybiB0fSwKRTpmdW5jdGlvbihhLGIpe3ZhciB0
+LHMscgpQLmsxKGIsImluZGV4IikKZm9yKHQ9dGhpcy5na3oodGhpcykscz0wO3QuRigpOyl7cj10Lmds
+KCkKaWYoYj09PXMpcmV0dXJuIHI7KytzfXRocm93IEguYihQLkNmKGIsdGhpcywiaW5kZXgiLG51bGws
+cykpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gUC5FUCh0aGlzLCIoIiwiKSIpfX0KUC5Bbi5wcm90b3R5
+cGU9e30KUC56TS5wcm90b3R5cGU9eyRpYlE6MSwkaWNYOjF9ClAuWjAucHJvdG90eXBlPXt9ClAuTjMu
+cHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iTWFwRW50cnkoIitILkVqKEouaih0aGlzLmEp
+KSsiOiAiK0guRWooSi5qKHRoaXMuYikpKyIpIn19ClAuYzgucHJvdG90eXBlPXsKZ2lPOmZ1bmN0aW9u
+KGEpe3JldHVybiBQLk1oLnByb3RvdHlwZS5naU8uY2FsbCh0aGlzLHRoaXMpfSwKdzpmdW5jdGlvbihh
+KXtyZXR1cm4ibnVsbCJ9fQpQLmxmLnByb3RvdHlwZT17fQpQLk1oLnByb3RvdHlwZT17Y29uc3RydWN0
+b3I6UC5NaCwkaU1oOjEsCkROOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXM9PT1ifSwKZ2lPOmZ1bmN0
+aW9uKGEpe3JldHVybiBILmVRKHRoaXMpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4iSW5zdGFuY2Ugb2Yg
+JyIrSC5FaihILk0odGhpcykpKyInIn0sCmU3OmZ1bmN0aW9uKGEsYil7dS5vLmEoYikKdGhyb3cgSC5i
+KFAubHIodGhpcyxiLmdXYSgpLGIuZ25kKCksYi5nVm0oKSkpfSwKdG9TdHJpbmc6ZnVuY3Rpb24oKXty
+ZXR1cm4gdGhpcy53KHRoaXMpfX0KUC5PZC5wcm90b3R5cGU9e30KUC5pYi5wcm90b3R5cGU9eyRpT2Q6
+MX0KUC54dS5wcm90b3R5cGU9e30KUC5Hei5wcm90b3R5cGU9e30KUC5aZC5wcm90b3R5cGU9ewp3OmZ1
+bmN0aW9uKGEpe3JldHVybiIifSwKJGlHejoxfQpQLnFVLnByb3RvdHlwZT17JGl2WDoxfQpQLlJuLnBy
+b3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEubGVuZ3RofSwKdzpmdW5jdGlvbihh
+KXt2YXIgdD10aGlzLmEKcmV0dXJuIHQuY2hhckNvZGVBdCgwKT09MD90OnR9LAokaUJMOjF9ClAuR0Qu
+cHJvdG90eXBlPXt9ClAubjEucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscQp1
+LmYuYShhKQpILmgoYikKdD1KLnJZKGIpLk9ZKGIsIj0iKQppZih0PT09LTEpe2lmKGIhPT0iIilhLlko
+MCxQLmt1KGIsMCxiLmxlbmd0aCx0aGlzLmEsITApLCIiKX1lbHNlIGlmKHQhPT0wKXtzPUMueEIuTmoo
+YiwwLHQpCnI9Qy54Qi5HKGIsdCsxKQpxPXRoaXMuYQphLlkoMCxQLmt1KHMsMCxzLmxlbmd0aCxxLCEw
+KSxQLmt1KHIsMCxyLmxlbmd0aCxxLCEwKSl9cmV0dXJuIGF9LAokUzoxOX0KUC5jUy5wcm90b3R5cGU9
+ewokMjpmdW5jdGlvbihhLGIpe3Rocm93IEguYihQLnJyKCJJbGxlZ2FsIElQdjQgYWRkcmVzcywgIith
+LHRoaXMuYSxiKSl9LAokUzo1MH0KUC5WQy5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3Rocm93
+IEguYihQLnJyKCJJbGxlZ2FsIElQdjYgYWRkcmVzcywgIithLHRoaXMuYSxiKSl9LAokMTpmdW5jdGlv
+bihhKXtyZXR1cm4gdGhpcy4kMihhLG51bGwpfSwKJFM6NTF9ClAuSlQucHJvdG90eXBlPXsKJDI6ZnVu
+Y3Rpb24oYSxiKXt2YXIgdAppZihiLWE+NCl0aGlzLmEuJDIoImFuIElQdjYgcGFydCBjYW4gb25seSBj
+b250YWluIGEgbWF4aW11bSBvZiA0IGhleCBkaWdpdHMiLGEpCnQ9UC5RQShDLnhCLk5qKHRoaXMuYixh
+LGIpLDE2KQppZih0eXBlb2YgdCE9PSJudW1iZXIiKXJldHVybiB0LkooKQppZih0PDB8fHQ+NjU1MzUp
+dGhpcy5hLiQyKCJlYWNoIHBhcnQgbXVzdCBiZSBpbiB0aGUgcmFuZ2Ugb2YgYDB4MC4uMHhGRkZGYCIs
+YSkKcmV0dXJuIHR9LAokUzoyMH0KUC5Ebi5wcm90b3R5cGU9ewpnbkQ6ZnVuY3Rpb24oKXt2YXIgdCxz
+LHIscT10aGlzLHA9cS54CmlmKHA9PW51bGwpe3A9cS5hCnQ9cC5sZW5ndGghPT0wPyIiK3ArIjoiOiIi
+CnM9cS5jCnI9cz09bnVsbAppZighcnx8cD09PSJmaWxlIil7cD10KyIvLyIKdD1xLmIKaWYodC5sZW5n
+dGghPT0wKXA9cCt0KyJAIgppZighcilwKz1zCnQ9cS5kCmlmKHQhPW51bGwpcD1wKyI6IitILkVqKHQp
+fWVsc2UgcD10CnArPXEuZQp0PXEuZgppZih0IT1udWxsKXA9cCsiPyIrdAp0PXEucgppZih0IT1udWxs
+KXA9cCsiIyIrdApwPXAuY2hhckNvZGVBdCgwKT09MD9wOnAKaWYocS54PT1udWxsKXEueD1wCmVsc2Ug
+cD1ILnZoKEgueVIoIkZpZWxkICdfdGV4dCcgaGFzIGJlZW4gYXNzaWduZWQgZHVyaW5nIGluaXRpYWxp
+emF0aW9uLiIpKX1yZXR1cm4gcH0sCmdGajpmdW5jdGlvbigpe3ZhciB0LHM9dGhpcyxyPXMueQppZihy
+PT1udWxsKXt0PXMuZQppZih0Lmxlbmd0aCE9PTAmJkMueEIuVyh0LDApPT09NDcpdD1DLnhCLkcodCwx
+KQpyPXQubGVuZ3RoPT09MD9DLnhEOlAuQUYobmV3IEgubEooSC5WTSh0LnNwbGl0KCIvIiksdS5zKSx1
+LmRPLmEoUC5QSCgpKSx1LmRvKSx1Lk4pCmlmKHMueT09bnVsbClzLnNLcChyKQplbHNlIHI9SC52aChI
+LnlSKCJGaWVsZCAncGF0aFNlZ21lbnRzJyBoYXMgYmVlbiBhc3NpZ25lZCBkdXJpbmcgaW5pdGlhbGl6
+YXRpb24uIikpfXJldHVybiByfSwKZ2lPOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMscz10LnoKaWYocz09
+bnVsbCl7cz1DLnhCLmdpTyh0LmduRCgpKQppZih0Lno9PW51bGwpdC56PXMKZWxzZSBzPUgudmgoSC55
+UigiRmllbGQgJ2hhc2hDb2RlJyBoYXMgYmVlbiBhc3NpZ25lZCBkdXJpbmcgaW5pdGlhbGl6YXRpb24u
+IikpfXJldHVybiBzfSwKZ2hZOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcyxzPXQuUQppZihzPT1udWxsKXtz
+PW5ldyBQLkdqKFAuV1godC5ndFAoKSksdS5kdykKaWYodC5RPT1udWxsKXQuc05NKHMpCmVsc2Ugcz1I
+LnZoKEgueVIoIkZpZWxkICdxdWVyeVBhcmFtZXRlcnMnIGhhcyBiZWVuIGFzc2lnbmVkIGR1cmluZyBp
+bml0aWFsaXphdGlvbi4iKSl9cmV0dXJuIHN9LApna3U6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5ifSwK
+Z0pmOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYwppZih0PT1udWxsKXJldHVybiIiCmlmKEMueEIubih0
+LCJbIikpcmV0dXJuIEMueEIuTmoodCwxLHQubGVuZ3RoLTEpCnJldHVybiB0fSwKZ3RwOmZ1bmN0aW9u
+KGEpe3ZhciB0PXRoaXMuZApyZXR1cm4gdD09bnVsbD9QLndLKHRoaXMuYSk6dH0sCmd0UDpmdW5jdGlv
+bigpe3ZhciB0PXRoaXMuZgpyZXR1cm4gdD09bnVsbD8iIjp0fSwKZ0thOmZ1bmN0aW9uKCl7dmFyIHQ9
+dGhpcy5yCnJldHVybiB0PT1udWxsPyIiOnR9LApubTpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAs
+byxuLG0sbCxrPXRoaXMKdS5VLmEobnVsbCkKdS5jOS5hKGIpCnQ9ay5hCnM9dD09PSJmaWxlIgpyPWsu
+YgpxPWsuZApwPWsuYwppZighKHAhPW51bGwpKXA9ci5sZW5ndGghPT0wfHxxIT1udWxsfHxzPyIiOm51
+bGwKbz1rLmUKaWYoIXMpbj1wIT1udWxsJiZvLmxlbmd0aCE9PTAKZWxzZSBuPSEwCmlmKG4mJiFDLnhC
+Lm4obywiLyIpKW89Ii8iK28KbT1vCmw9UC5sZShudWxsLDAsMCxiKQpyZXR1cm4gbmV3IFAuRG4odCxy
+LHAscSxtLGwsay5yKX0sCkpoOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvCmZvcih0PTAscz0w
+O0MueEIuUWkoYiwiLi4vIixzKTspe3MrPTM7Kyt0fXI9Qy54Qi5jbihhLCIvIikKd2hpbGUoITApe2lm
+KCEocj4wJiZ0PjApKWJyZWFrCnE9Qy54Qi5QayhhLCIvIixyLTEpCmlmKHE8MClicmVhawpwPXItcQpv
+PXAhPT0yCmlmKCFvfHxwPT09MylpZihDLnhCLm0oYSxxKzEpPT09NDYpbz0hb3x8Qy54Qi5tKGEscSsy
+KT09PTQ2CmVsc2Ugbz0hMQplbHNlIG89ITEKaWYobylicmVhazstLXQKcj1xfXJldHVybiBDLnhCLmk3
+KGEscisxLG51bGwsQy54Qi5HKGIscy0zKnQpKX0sClpJOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLm1T
+KFAuaEsoYSkpfSwKbVM6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGs9dGhpcyxqPW51
+bGwKaWYoYS5nRmkoKS5sZW5ndGghPT0wKXt0PWEuZ0ZpKCkKaWYoYS5nY2ooKSl7cz1hLmdrdSgpCnI9
+YS5nSmYoYSkKcT1hLmd4QSgpP2EuZ3RwKGEpOmp9ZWxzZXtxPWoKcj1xCnM9IiJ9cD1QLnhlKGEuZ0lp
+KGEpKQpvPWEuZ1FEKCk/YS5ndFAoKTpqfWVsc2V7dD1rLmEKaWYoYS5nY2ooKSl7cz1hLmdrdSgpCnI9
+YS5nSmYoYSkKcT1QLndCKGEuZ3hBKCk/YS5ndHAoYSk6aix0KQpwPVAueGUoYS5nSWkoYSkpCm89YS5n
+UUQoKT9hLmd0UCgpOmp9ZWxzZXtzPWsuYgpyPWsuYwpxPWsuZAppZihhLmdJaShhKT09PSIiKXtwPWsu
+ZQpvPWEuZ1FEKCk/YS5ndFAoKTprLmZ9ZWxzZXtpZihhLmd0VCgpKXA9UC54ZShhLmdJaShhKSkKZWxz
+ZXtuPWsuZQppZihuLmxlbmd0aD09PTApaWYocj09bnVsbClwPXQubGVuZ3RoPT09MD9hLmdJaShhKTpQ
+LnhlKGEuZ0lpKGEpKQplbHNlIHA9UC54ZSgiLyIrYS5nSWkoYSkpCmVsc2V7bT1rLkpoKG4sYS5nSWko
+YSkpCmw9dC5sZW5ndGg9PT0wCmlmKCFsfHxyIT1udWxsfHxDLnhCLm4obiwiLyIpKXA9UC54ZShtKQpl
+bHNlIHA9UC53RihtLCFsfHxyIT1udWxsKX19bz1hLmdRRCgpP2EuZ3RQKCk6an19fXJldHVybiBuZXcg
+UC5Ebih0LHMscixxLHAsbyxhLmdaOCgpP2EuZ0thKCk6ail9LApnY2o6ZnVuY3Rpb24oKXtyZXR1cm4g
+dGhpcy5jIT1udWxsfSwKZ3hBOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZCE9bnVsbH0sCmdRRDpmdW5j
+dGlvbigpe3JldHVybiB0aGlzLmYhPW51bGx9LApnWjg6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5yIT1u
+dWxsfSwKZ3RUOmZ1bmN0aW9uKCl7cmV0dXJuIEMueEIubih0aGlzLmUsIi8iKX0sCnQ0OmZ1bmN0aW9u
+KCl7dmFyIHQscz10aGlzLHI9cy5hCmlmKHIhPT0iIiYmciE9PSJmaWxlIil0aHJvdyBILmIoUC5MNCgi
+Q2Fubm90IGV4dHJhY3QgYSBmaWxlIHBhdGggZnJvbSBhICIrcisiIFVSSSIpKQppZihzLmd0UCgpIT09
+IiIpdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBleHRyYWN0IGEgZmlsZSBwYXRoIGZyb20gYSBVUkkgd2l0
+aCBhIHF1ZXJ5IGNvbXBvbmVudCIpKQppZihzLmdLYSgpIT09IiIpdGhyb3cgSC5iKFAuTDQoIkNhbm5v
+dCBleHRyYWN0IGEgZmlsZSBwYXRoIGZyb20gYSBVUkkgd2l0aCBhIGZyYWdtZW50IGNvbXBvbmVudCIp
+KQpyPSQud1EoKQppZihILm9UKHIpKXI9UC5tbihzKQplbHNle2lmKHMuYyE9bnVsbCYmcy5nSmYocykh
+PT0iIilILnZoKFAuTDQoIkNhbm5vdCBleHRyYWN0IGEgbm9uLVdpbmRvd3MgZmlsZSBwYXRoIGZyb20g
+YSBmaWxlIFVSSSB3aXRoIGFuIGF1dGhvcml0eSIpKQp0PXMuZ0ZqKCkKUC5rRSh0LCExKQpyPVAudmco
+Qy54Qi5uKHMuZSwiLyIpPyIiKyIvIjoiIix0LCIvIikKcj1yLmNoYXJDb2RlQXQoMCk9PTA/cjpyfXJl
+dHVybiByfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5nbkQoKX0sCkROOmZ1bmN0aW9uKGEsYil7
+dmFyIHQ9dGhpcwppZihiPT1udWxsKXJldHVybiExCmlmKHQ9PT1iKXJldHVybiEwCnJldHVybiB1LmRE
+LmIoYikmJnQuYT09PWIuZ0ZpKCkmJnQuYyE9bnVsbD09PWIuZ2NqKCkmJnQuYj09PWIuZ2t1KCkmJnQu
+Z0pmKHQpPT09Yi5nSmYoYikmJnQuZ3RwKHQpPT09Yi5ndHAoYikmJnQuZT09PWIuZ0lpKGIpJiZ0LmYh
+PW51bGw9PT1iLmdRRCgpJiZ0Lmd0UCgpPT09Yi5ndFAoKSYmdC5yIT1udWxsPT09Yi5nWjgoKSYmdC5n
+S2EoKT09PWIuZ0thKCl9LApzS3A6ZnVuY3Rpb24oYSl7dGhpcy55PXUuYmsuYShhKX0sCnNOTTpmdW5j
+dGlvbihhKXt0aGlzLlE9dS5jWi5hKGEpfSwKJGlpRDoxLApnRmk6ZnVuY3Rpb24oKXtyZXR1cm4gdGhp
+cy5hfSwKZ0lpOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmV9fQpQLlJaLnByb3RvdHlwZT17CiQxOmZ1
+bmN0aW9uKGEpe3JldHVybiBQLmVQKEMuWkosSC5oKGEpLEMueE0sITEpfSwKJFM6Nn0KUC5NRS5wcm90
+b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciB0PXRoaXMuYixzPXRoaXMuYQp0LmErPXMuYQpzLmE9
+IiYiCnM9dC5hKz1ILkVqKFAuZVAoQy5GMyxhLEMueE0sITApKQppZihiIT1udWxsJiZiLmxlbmd0aCE9
+PTApe3QuYT1zKyI9Igp0LmErPUguRWooUC5lUChDLkYzLGIsQy54TSwhMCkpfX0sCiRTOjIyfQpQLnk1
+LnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHQscwpILmgoYSkKaWYoYj09bnVsbHx8dHlw
+ZW9mIGI9PSJzdHJpbmciKXRoaXMuYS4kMihhLEguayhiKSkKZWxzZSBmb3IodD1KLklUKHUubS5hKGIp
+KSxzPXRoaXMuYTt0LkYoKTspcy4kMihhLEguaCh0LmdsKCkpKX0sCiRTOjEyfQpQLlBFLnByb3RvdHlw
ZT17CmdsUjpmdW5jdGlvbigpe3ZhciB0LHMscixxLHA9dGhpcyxvPW51bGwsbj1wLmMKaWYobj09bnVs
-bCl7bj1wLmIKaWYoMD49bi5sZW5ndGgpcmV0dXJuIEguayhuLDApCnQ9cC5hCm49blswXSsxCnM9Qy54
-Qi5YVSh0LCI/IixuKQpyPXQubGVuZ3RoCmlmKHM+PTApe3E9UC5QSSh0LHMrMSxyLEMuVkMsITEpCnI9
-c31lbHNlIHE9bwpuPXAuYz1uZXcgUC5xZSgiZGF0YSIsIiIsbyxvLFAuUEkodCxuLHIsQy5XZCwhMSks
-cSxvKX1yZXR1cm4gbn0sClo6ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzLmIKaWYoMD49cy5sZW5ndGgp
-cmV0dXJuIEguayhzLDApCnQ9dGhpcy5hCnJldHVybiBzWzBdPT09LTE/ImRhdGE6Iit0OnR9fQpQLnEz
-LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgVWludDhBcnJheSg5Nil9LAokUzoy
-M30KUC55SS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciB0PXRoaXMuYQppZihhPj10Lmxl
-bmd0aClyZXR1cm4gSC5rKHQsYSkKdD10W2FdCkouQ00odCwwLDk2LGIpCnJldHVybiB0fSwKJFM6MjR9
-ClAuYzYucHJvdG90eXBlPXsKJDM6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxCmZvcih0PWIubGVu
-Z3RoLHM9YS5sZW5ndGgscj0wO3I8dDsrK3Ipe3E9Qy54Qi5XKGIscileOTYKaWYocT49cylyZXR1cm4g
-SC5rKGEscSkKYVtxXT1jfX19ClAucWQucHJvdG90eXBlPXsKJDM6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0
-LHMscixxCmZvcih0PUMueEIuVyhiLDApLHM9Qy54Qi5XKGIsMSkscj1hLmxlbmd0aDt0PD1zOysrdCl7
-cT0odF45Nik+Pj4wCmlmKHE+PXIpcmV0dXJuIEguayhhLHEpCmFbcV09Y319fQpQLlVmLnByb3RvdHlw
-ZT17CmdjajpmdW5jdGlvbigpe3JldHVybiB0aGlzLmM+MH0sCmd4QTpmdW5jdGlvbigpe3JldHVybiB0
-aGlzLmM+MCYmdGhpcy5kKzE8dGhpcy5lfSwKZ1FEOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZjx0aGlz
-LnJ9LApnWjg6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5yPHRoaXMuYS5sZW5ndGh9LApnTnc6ZnVuY3Rp
-b24oKXtyZXR1cm4gdGhpcy5iPT09NCYmQy54Qi5uKHRoaXMuYSwiZmlsZSIpfSwKZ3ZoOmZ1bmN0aW9u
-KCl7cmV0dXJuIHRoaXMuYj09PTQmJkMueEIubih0aGlzLmEsImh0dHAiKX0sCmdSZTpmdW5jdGlvbigp
-e3JldHVybiB0aGlzLmI9PT01JiZDLnhCLm4odGhpcy5hLCJodHRwcyIpfSwKZ3RUOmZ1bmN0aW9uKCl7
-cmV0dXJuIEMueEIuUWkodGhpcy5hLCIvIix0aGlzLmUpfSwKZ0ZpOmZ1bmN0aW9uKCl7dmFyIHQ9dGhp
-cy54CnJldHVybiB0PT1udWxsP3RoaXMueD10aGlzLlUyKCk6dH0sClUyOmZ1bmN0aW9uKCl7dmFyIHQ9
-dGhpcyxzPXQuYgppZihzPD0wKXJldHVybiIiCmlmKHQuZ3ZoKCkpcmV0dXJuImh0dHAiCmlmKHQuZ1Jl
-KCkpcmV0dXJuImh0dHBzIgppZih0LmdOdygpKXJldHVybiJmaWxlIgppZihzPT09NyYmQy54Qi5uKHQu
-YSwicGFja2FnZSIpKXJldHVybiJwYWNrYWdlIgpyZXR1cm4gQy54Qi5Oaih0LmEsMCxzKX0sCmdrdTpm
-dW5jdGlvbigpe3ZhciB0PXRoaXMuYyxzPXRoaXMuYiszCnJldHVybiB0PnM/Qy54Qi5Oaih0aGlzLmEs
-cyx0LTEpOiIifSwKZ0pmOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYwpyZXR1cm4gdD4wP0MueEIuTmoo
-dGhpcy5hLHQsdGhpcy5kKToiIn0sCmd0cDpmdW5jdGlvbihhKXt2YXIgdD10aGlzCmlmKHQuZ3hBKCkp
-cmV0dXJuIFAuUUEoQy54Qi5Oaih0LmEsdC5kKzEsdC5lKSxudWxsKQppZih0Lmd2aCgpKXJldHVybiA4
-MAppZih0LmdSZSgpKXJldHVybiA0NDMKcmV0dXJuIDB9LApnSWk6ZnVuY3Rpb24oYSl7cmV0dXJuIEMu
-eEIuTmoodGhpcy5hLHRoaXMuZSx0aGlzLmYpfSwKZ3RQOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5mLHM9
-dGhpcy5yCnJldHVybiB0PHM/Qy54Qi5Oaih0aGlzLmEsdCsxLHMpOiIifSwKZ0thOmZ1bmN0aW9uKCl7
-dmFyIHQ9dGhpcy5yLHM9dGhpcy5hCnJldHVybiB0PHMubGVuZ3RoP0MueEIuRyhzLHQrMSk6IiJ9LApn
-Rmo6ZnVuY3Rpb24oKXt2YXIgdCxzLHI9dGhpcy5lLHE9dGhpcy5mLHA9dGhpcy5hCmlmKEMueEIuUWko
-cCwiLyIscikpKytyCmlmKHI9PT1xKXJldHVybiBDLnhECnQ9SC5WTShbXSx1LnMpCmZvcihzPXI7czxx
-OysrcylpZihDLnhCLm0ocCxzKT09PTQ3KXtDLk5tLmkodCxDLnhCLk5qKHAscixzKSkKcj1zKzF9Qy5O
-bS5pKHQsQy54Qi5OaihwLHIscSkpCnJldHVybiBQLkFGKHQsdS5OKX0sCmdoWTpmdW5jdGlvbigpe2lm
-KHRoaXMuZj49dGhpcy5yKXJldHVybiBDLldPCnJldHVybiBuZXcgUC5HaihQLldYKHRoaXMuZ3RQKCkp
-LHUuRCl9LAprWDpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmQrMQpyZXR1cm4gdCthLmxlbmd0aD09PXRo
-aXMuZSYmQy54Qi5RaSh0aGlzLmEsYSx0KX0sCk45OmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcyxzPXQucixy
-PXQuYQppZihzPj1yLmxlbmd0aClyZXR1cm4gdApyZXR1cm4gbmV3IFAuVWYoQy54Qi5OaihyLDAscyks
-dC5iLHQuYyx0LmQsdC5lLHQuZixzLHQueCl9LApubTpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAs
-byxuLG0sbCxrLGo9dGhpcyxpPW51bGwKdS5YLmEobnVsbCkKdS5iLmEoYikKdD1qLmdGaSgpCnM9dD09
-PSJmaWxlIgpyPWouYwpxPXI+MD9DLnhCLk5qKGouYSxqLmIrMyxyKToiIgpwPWouZ3hBKCk/ai5ndHAo
-aik6aQpyPWouYwppZihyPjApbz1DLnhCLk5qKGouYSxyLGouZCkKZWxzZSBvPXEubGVuZ3RoIT09MHx8
-cCE9bnVsbHx8cz8iIjppCnI9ai5hCm49Qy54Qi5OaihyLGouZSxqLmYpCmlmKCFzKW09byE9bnVsbCYm
-bi5sZW5ndGghPT0wCmVsc2UgbT0hMAppZihtJiYhQy54Qi5uKG4sIi8iKSluPSIvIituCmw9UC5sZShp
-LDAsMCxiKQptPWoucgprPW08ci5sZW5ndGg/Qy54Qi5HKHIsbSsxKTppCnJldHVybiBuZXcgUC5Ebih0
-LHEsbyxwLG4sbCxrKX0sClpJOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLm1TKFAuaEsoYSkpfSwKbVM6
-ZnVuY3Rpb24oYSl7aWYoYSBpbnN0YW5jZW9mIFAuVWYpcmV0dXJuIHRoaXMudTEodGhpcyxhKQpyZXR1
-cm4gdGhpcy52cygpLm1TKGEpfSwKdTE6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG8sbixtLGws
-ayxqLGksaD1iLmIKaWYoaD4wKXJldHVybiBiCnQ9Yi5jCmlmKHQ+MCl7cz1hLmIKaWYoczw9MClyZXR1
-cm4gYgppZihhLmdOdygpKXI9Yi5lIT09Yi5mCmVsc2UgaWYoYS5ndmgoKSlyPSFiLmtYKCI4MCIpCmVs
-c2Ugcj0hYS5nUmUoKXx8IWIua1goIjQ0MyIpCmlmKHIpe3E9cysxCnJldHVybiBuZXcgUC5VZihDLnhC
-Lk5qKGEuYSwwLHEpK0MueEIuRyhiLmEsaCsxKSxzLHQrcSxiLmQrcSxiLmUrcSxiLmYrcSxiLnIrcSxh
-LngpfWVsc2UgcmV0dXJuIHRoaXMudnMoKS5tUyhiKX1wPWIuZQpoPWIuZgppZihwPT09aCl7dD1iLnIK
-aWYoaDx0KXtzPWEuZgpxPXMtaApyZXR1cm4gbmV3IFAuVWYoQy54Qi5OaihhLmEsMCxzKStDLnhCLkco
-Yi5hLGgpLGEuYixhLmMsYS5kLGEuZSxoK3EsdCtxLGEueCl9aD1iLmEKaWYodDxoLmxlbmd0aCl7cz1h
-LnIKcmV0dXJuIG5ldyBQLlVmKEMueEIuTmooYS5hLDAscykrQy54Qi5HKGgsdCksYS5iLGEuYyxhLmQs
-YS5lLGEuZix0KyhzLXQpLGEueCl9cmV0dXJuIGEuTjkoKX10PWIuYQppZihDLnhCLlFpKHQsIi8iLHAp
-KXtzPWEuZQpxPXMtcApyZXR1cm4gbmV3IFAuVWYoQy54Qi5OaihhLmEsMCxzKStDLnhCLkcodCxwKSxh
-LmIsYS5jLGEuZCxzLGgrcSxiLnIrcSxhLngpfW89YS5lCm49YS5mCmlmKG89PT1uJiZhLmM+MCl7Zm9y
-KDtDLnhCLlFpKHQsIi4uLyIscCk7KXArPTMKcT1vLXArMQpyZXR1cm4gbmV3IFAuVWYoQy54Qi5Oaihh
-LmEsMCxvKSsiLyIrQy54Qi5HKHQscCksYS5iLGEuYyxhLmQsbyxoK3EsYi5yK3EsYS54KX1tPWEuYQpm
-b3IobD1vO0MueEIuUWkobSwiLi4vIixsKTspbCs9MwprPTAKd2hpbGUoITApe2o9cCszCmlmKCEoajw9
-aCYmQy54Qi5RaSh0LCIuLi8iLHApKSlicmVhazsrK2sKcD1qfWZvcihpPSIiO24+bDspey0tbgppZihD
-LnhCLm0obSxuKT09PTQ3KXtpZihrPT09MCl7aT0iLyIKYnJlYWt9LS1rCmk9Ii8ifX1pZihuPT09bCYm
-YS5iPD0wJiYhQy54Qi5RaShtLCIvIixvKSl7cC09ayozCmk9IiJ9cT1uLXAraS5sZW5ndGgKcmV0dXJu
-IG5ldyBQLlVmKEMueEIuTmoobSwwLG4pK2krQy54Qi5HKHQscCksYS5iLGEuYyxhLmQsbyxoK3EsYi5y
-K3EsYS54KX0sCnQ0OmZ1bmN0aW9uKCl7dmFyIHQscyxyLHE9dGhpcwppZihxLmI+PTAmJiFxLmdOdygp
-KXRocm93IEguYihQLkw0KCJDYW5ub3QgZXh0cmFjdCBhIGZpbGUgcGF0aCBmcm9tIGEgIitxLmdGaSgp
-KyIgVVJJIikpCnQ9cS5mCnM9cS5hCmlmKHQ8cy5sZW5ndGgpe2lmKHQ8cS5yKXRocm93IEguYihQLkw0
-KCJDYW5ub3QgZXh0cmFjdCBhIGZpbGUgcGF0aCBmcm9tIGEgVVJJIHdpdGggYSBxdWVyeSBjb21wb25l
-bnQiKSkKdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBleHRyYWN0IGEgZmlsZSBwYXRoIGZyb20gYSBVUkkg
-d2l0aCBhIGZyYWdtZW50IGNvbXBvbmVudCIpKX1yPSQuT3goKQppZihILm9UKHIpKXQ9UC5tbihxKQpl
-bHNle2lmKHEuYzxxLmQpSC52aChQLkw0KCJDYW5ub3QgZXh0cmFjdCBhIG5vbi1XaW5kb3dzIGZpbGUg
-cGF0aCBmcm9tIGEgZmlsZSBVUkkgd2l0aCBhbiBhdXRob3JpdHkiKSkKdD1DLnhCLk5qKHMscS5lLHQp
-fXJldHVybiB0fSwKZ2lPOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMueQpyZXR1cm4gdD09bnVsbD90aGlz
-Lnk9Qy54Qi5naU8odGhpcy5hKTp0fSwKRE46ZnVuY3Rpb24oYSxiKXtpZihiPT1udWxsKXJldHVybiEx
-CmlmKHRoaXM9PT1iKXJldHVybiEwCnJldHVybiB1LkYuYihiKSYmdGhpcy5hPT09Yi5aKDApfSwKdnM6
-ZnVuY3Rpb24oKXt2YXIgdD10aGlzLHM9bnVsbCxyPXQuZ0ZpKCkscT10LmdrdSgpLHA9dC5jPjA/dC5n
-SmYodCk6cyxvPXQuZ3hBKCk/dC5ndHAodCk6cyxuPXQuYSxtPXQuZixsPUMueEIuTmoobix0LmUsbSks
-az10LnIKbT1tPGs/dC5ndFAoKTpzCnJldHVybiBuZXcgUC5EbihyLHEscCxvLGwsbSxrPG4ubGVuZ3Ro
-P3QuZ0thKCk6cyl9LApaOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmF9LAokaWlEOjF9ClAucWUucHJv
-dG90eXBlPXt9ClcucUUucHJvdG90eXBlPXt9ClcuR2gucHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXty
-ZXR1cm4gU3RyaW5nKGEpfSwKJGlHaDoxfQpXLmZZLnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7cmV0
-dXJuIFN0cmluZyhhKX19ClcubkIucHJvdG90eXBlPXskaW5COjF9ClcuQXoucHJvdG90eXBlPXskaUF6
-OjF9ClcuUVAucHJvdG90eXBlPXskaVFQOjF9ClcubngucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7
-cmV0dXJuIGEubGVuZ3RofX0KVy5vSi5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5s
-ZW5ndGh9fQpXLmlkLnByb3RvdHlwZT17fQpXLlFGLnByb3RvdHlwZT17fQpXLk5oLnByb3RvdHlwZT17
-Clo6ZnVuY3Rpb24oYSl7cmV0dXJuIFN0cmluZyhhKX19ClcuSUIucHJvdG90eXBlPXsKWjpmdW5jdGlv
-bihhKXtyZXR1cm4iUmVjdGFuZ2xlICgiK0guZChhLmxlZnQpKyIsICIrSC5kKGEudG9wKSsiKSAiK0gu
-ZChhLndpZHRoKSsiIHggIitILmQoYS5oZWlnaHQpfSwKRE46ZnVuY3Rpb24oYSxiKXtpZihiPT1udWxs
-KXJldHVybiExCnJldHVybiB1Lk8uYihiKSYmYS5sZWZ0PT1iLmxlZnQmJmEudG9wPT1iLnRvcCYmYS53
-aWR0aD09Yi53aWR0aCYmYS5oZWlnaHQ9PWIuaGVpZ2h0fSwKZ2lPOmZ1bmN0aW9uKGEpe3JldHVybiBX
-LnJFKEouaGYoYS5sZWZ0KSxKLmhmKGEudG9wKSxKLmhmKGEud2lkdGgpLEouaGYoYS5oZWlnaHQpKX0s
-CiRpdG46MX0KVy5uNy5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9fQpX
-Lnd6LnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEubGVuZ3RofSwKcTpmdW5j
-dGlvbihhLGIpe3ZhciB0CkguV1koYikKdD10aGlzLmEKaWYoYjwwfHxiPj10Lmxlbmd0aClyZXR1cm4g
-SC5rKHQsYikKcmV0dXJuIHRoaXMuJHRpLmMuYSh0W2JdKX0sClk6ZnVuY3Rpb24oYSxiLGMpe3RoaXMu
-JHRpLmMuYShjKQp0aHJvdyBILmIoUC5MNCgiQ2Fubm90IG1vZGlmeSBsaXN0IikpfX0KVy5jdi5wcm90
-b3R5cGU9ewpnUWc6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBXLmk3KGEpfSwKZ1A6ZnVuY3Rpb24oYSl7
-cmV0dXJuIG5ldyBXLkk0KGEpfSwKc1A6ZnVuY3Rpb24oYSxiKXt2YXIgdAp1LlguYShiKQp0PXRoaXMu
-Z1AoYSkKdC5WMSgwKQp0LkZWKDAsYil9LApaOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxvY2FsTmFtZX0s
-CkZGOmZ1bmN0aW9uKGEpe3ZhciB0PSEhYS5zY3JvbGxJbnRvVmlld0lmTmVlZGVkCmlmKHQpYS5zY3Jv
-bGxJbnRvVmlld0lmTmVlZGVkKCkKZWxzZSBhLnNjcm9sbEludG9WaWV3KCl9LApuejpmdW5jdGlvbihh
-LGIsYyxkLGUpe3ZhciB0LHM9dGhpcy5yNihhLGMsZCxlKQpzd2l0Y2goYi50b0xvd2VyQ2FzZSgpKXtj
-YXNlImJlZm9yZWJlZ2luIjphLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKHMsYSkKYnJlYWsKY2FzZSJh
-ZnRlcmJlZ2luIjp0PWEuY2hpbGROb2RlcwphLmluc2VydEJlZm9yZShzLHQubGVuZ3RoPjA/dFswXTpu
-dWxsKQpicmVhawpjYXNlImJlZm9yZWVuZCI6YS5hcHBlbmRDaGlsZChzKQpicmVhawpjYXNlImFmdGVy
-ZW5kIjp0PWEucGFyZW50Tm9kZQp0LnRvU3RyaW5nCnQuaW5zZXJ0QmVmb3JlKHMsYS5uZXh0U2libGlu
-ZykKYnJlYWsKZGVmYXVsdDpILnZoKFAueFkoIkludmFsaWQgcG9zaXRpb24gIitiKSl9fSwKcjY6ZnVu
-Y3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyLHEKaWYoYz09bnVsbCl7aWYoZD09bnVsbCl7dD0kLmx0Cmlm
-KHQ9PW51bGwpe3Q9SC5WTShbXSx1LmspCnM9bmV3IFcudkQodCkKQy5ObS5pKHQsVy5UdyhudWxsKSkK
-Qy5ObS5pKHQsVy5CbCgpKQokLmx0PXMKZD1zfWVsc2UgZD10fXQ9JC5FVQppZih0PT1udWxsKXt0PW5l
-dyBXLktvKGQpCiQuRVU9dApjPXR9ZWxzZXt0LmE9ZApjPXR9fWVsc2UgaWYoZCE9bnVsbCl0aHJvdyBI
-LmIoUC54WSgidmFsaWRhdG9yIGNhbiBvbmx5IGJlIHBhc3NlZCBpZiB0cmVlU2FuaXRpemVyIGlzIG51
-bGwiKSkKaWYoJC54bz09bnVsbCl7dD1kb2N1bWVudApzPXQuaW1wbGVtZW50YXRpb24uY3JlYXRlSFRN
-TERvY3VtZW50KCIiKQokLnhvPXMKJC5CTz1zLmNyZWF0ZVJhbmdlKCkKcz0kLnhvLmNyZWF0ZUVsZW1l
-bnQoImJhc2UiKQp1LmNSLmEocykKcy5ocmVmPXQuYmFzZVVSSQokLnhvLmhlYWQuYXBwZW5kQ2hpbGQo
-cyl9dD0kLnhvCmlmKHQuYm9keT09bnVsbCl7cz10LmNyZWF0ZUVsZW1lbnQoImJvZHkiKQp0LmJvZHk9
-dS5pLmEocyl9dD0kLnhvCmlmKHUuaS5iKGEpKXt0PXQuYm9keQp0LnRvU3RyaW5nCnI9dH1lbHNle3Qu
-dG9TdHJpbmcKcj10LmNyZWF0ZUVsZW1lbnQoYS50YWdOYW1lKQokLnhvLmJvZHkuYXBwZW5kQ2hpbGQo
-cil9aWYoImNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudCIgaW4gd2luZG93LlJhbmdlLnByb3RvdHlwZSYm
-IUMuTm0udGcoQy5TcSxhLnRhZ05hbWUpKXskLkJPLnNlbGVjdE5vZGVDb250ZW50cyhyKQpxPSQuQk8u
-Y3JlYXRlQ29udGV4dHVhbEZyYWdtZW50KGIpfWVsc2V7ci5pbm5lckhUTUw9YgpxPSQueG8uY3JlYXRl
-RG9jdW1lbnRGcmFnbWVudCgpCmZvcig7dD1yLmZpcnN0Q2hpbGQsdCE9bnVsbDspcS5hcHBlbmRDaGls
-ZCh0KX1pZihyIT09JC54by5ib2R5KUouTHQocikKYy5QbihxKQpkb2N1bWVudC5hZG9wdE5vZGUocSkK
-cmV0dXJuIHF9LApBSDpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIHRoaXMucjYoYSxiLGMsbnVsbCl9LApz
-aGY6ZnVuY3Rpb24oYSxiKXt0aGlzLllDKGEsYil9LApwazpmdW5jdGlvbihhLGIsYyl7YS50ZXh0Q29u
-dGVudD1udWxsCmEuYXBwZW5kQ2hpbGQodGhpcy5yNihhLGIsbnVsbCxjKSl9LApZQzpmdW5jdGlvbihh
-LGIpe3JldHVybiB0aGlzLnBrKGEsYixudWxsKX0sCmduczpmdW5jdGlvbihhKXtyZXR1cm4gYS50YWdO
-YW1lfSwKZ1ZsOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgVy5ldShhLCJjbGljayIsITEsdS5RKX0sCiRp
-Y3Y6MX0KVy5Ddi5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdS5oLmIodS5BLmEoYSkp
-fSwKJFM6MjV9ClcuZWEucHJvdG90eXBlPXskaWVhOjF9ClcuRDAucHJvdG90eXBlPXsKT246ZnVuY3Rp
-b24oYSxiLGMsZCl7dS5VLmEoYykKaWYoYyE9bnVsbCl0aGlzLnYoYSxiLGMsZCl9LApCOmZ1bmN0aW9u
-KGEsYixjKXtyZXR1cm4gdGhpcy5PbihhLGIsYyxudWxsKX0sCnY6ZnVuY3Rpb24oYSxiLGMsZCl7cmV0
-dXJuIGEuYWRkRXZlbnRMaXN0ZW5lcihiLEgudFIodS5VLmEoYyksMSksZCl9LAokaUQwOjF9ClcuVDUu
-cHJvdG90eXBlPXskaVQ1OjF9ClcuaDQucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEu
-bGVuZ3RofX0KVy5ici5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9fQpX
-LlZiLnByb3RvdHlwZT17fQpXLmZKLnByb3RvdHlwZT17CmVvOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVy
-biBhLm9wZW4oYixjLCEwKX0sCiRpZko6MX0KVy5iVS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIp
-e3RoaXMuYS5zZXRSZXF1ZXN0SGVhZGVyKEguYyhhKSxILmMoYikpfSwKJFM6OH0KVy5oSC5wcm90b3R5
-cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwCnUucC5hKGEpCnQ9dGhpcy5hCnM9dC5zdGF0
-dXMKaWYodHlwZW9mIHMhPT0ibnVtYmVyIilyZXR1cm4gcy50QigpCnI9cz49MjAwJiZzPDMwMApxPXM+
-MzA3JiZzPDQwMApzPXJ8fHM9PT0wfHxzPT09MzA0fHxxCnA9dGhpcy5iCmlmKHMpcC5hTSgwLHQpCmVs
-c2UgcC5wbShhKX0sCiRTOjE0fQpXLndhLnByb3RvdHlwZT17fQpXLlNnLnByb3RvdHlwZT17JGlTZzox
-fQpXLnU4LnByb3RvdHlwZT17CmdEcjpmdW5jdGlvbihhKXtpZigib3JpZ2luIiBpbiBhKXJldHVybiBh
-Lm9yaWdpbgpyZXR1cm4gSC5kKGEucHJvdG9jb2wpKyIvLyIrSC5kKGEuaG9zdCl9LApaOmZ1bmN0aW9u
-KGEpe3JldHVybiBTdHJpbmcoYSl9LAokaXU4OjF9ClcuT0sucHJvdG90eXBlPXskaU9LOjF9ClcuZTcu
-cHJvdG90eXBlPXsKZ3I4OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYSxzPXQuY2hpbGROb2Rlcy5sZW5n
-dGgKaWYocz09PTApdGhyb3cgSC5iKFAuUFYoIk5vIGVsZW1lbnRzIikpCmlmKHM+MSl0aHJvdyBILmIo
-UC5QVigiTW9yZSB0aGFuIG9uZSBlbGVtZW50IikpCnJldHVybiB0LmZpcnN0Q2hpbGR9LApGVjpmdW5j
-dGlvbihhLGIpe3ZhciB0LHMscixxLHAKdS5laC5hKGIpCnQ9Yi5hCnM9dGhpcy5hCmlmKHQhPT1zKWZv
-cihyPXQuY2hpbGROb2Rlcy5sZW5ndGgscT0wO3E8cjsrK3Epe3A9dC5maXJzdENoaWxkCnAudG9TdHJp
-bmcKcy5hcHBlbmRDaGlsZChwKX1yZXR1cm59LApZOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzCnUuQS5h
-KGMpCnQ9dGhpcy5hCnM9dC5jaGlsZE5vZGVzCmlmKGI8MHx8Yj49cy5sZW5ndGgpcmV0dXJuIEguayhz
-LGIpCnQucmVwbGFjZUNoaWxkKGMsc1tiXSl9LApna3o6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hLmNo
-aWxkTm9kZXMKcmV0dXJuIG5ldyBXLlc5KHQsdC5sZW5ndGgsSC5xKHQpLkMoIlc5PEdtLkU+IikpfSwK
-Z0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5jaGlsZE5vZGVzLmxlbmd0aH0sCnE6ZnVuY3Rpb24o
-YSxiKXt2YXIgdApILldZKGIpCnQ9dGhpcy5hLmNoaWxkTm9kZXMKaWYoYjwwfHxiPj10Lmxlbmd0aCly
-ZXR1cm4gSC5rKHQsYikKcmV0dXJuIHRbYl19fQpXLnVILnByb3RvdHlwZT17CndnOmZ1bmN0aW9uKGEp
-e3ZhciB0PWEucGFyZW50Tm9kZQppZih0IT1udWxsKXQucmVtb3ZlQ2hpbGQoYSl9LApENDpmdW5jdGlv
-bihhKXt2YXIgdApmb3IoO3Q9YS5maXJzdENoaWxkLHQhPW51bGw7KWEucmVtb3ZlQ2hpbGQodCl9LApa
-OmZ1bmN0aW9uKGEpe3ZhciB0PWEubm9kZVZhbHVlCnJldHVybiB0PT1udWxsP3RoaXMuVShhKTp0fSwK
-JGl1SDoxfQpXLkJILnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH0sCnE6
-ZnVuY3Rpb24oYSxiKXtILldZKGIpCmlmKGI+Pj4wIT09Ynx8Yj49YS5sZW5ndGgpdGhyb3cgSC5iKFAu
-dChiLGEsbnVsbCxudWxsLG51bGwpKQpyZXR1cm4gYVtiXX0sClk6ZnVuY3Rpb24oYSxiLGMpe3UuQS5h
-KGMpCnRocm93IEguYihQLkw0KCJDYW5ub3QgYXNzaWduIGVsZW1lbnQgb2YgaW1tdXRhYmxlIExpc3Qu
-IikpfSwKRTpmdW5jdGlvbihhLGIpe2lmKGI8MHx8Yj49YS5sZW5ndGgpcmV0dXJuIEguayhhLGIpCnJl
-dHVybiBhW2JdfSwKJGliUToxLAokaVhqOjEsCiRpY1g6MSwKJGl6TToxfQpXLlNOLnByb3RvdHlwZT17
-fQpXLmV3LnByb3RvdHlwZT17JGlldzoxfQpXLmxwLnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3Jl
-dHVybiBhLmxlbmd0aH19ClcuVGIucHJvdG90eXBlPXsKcjY6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQs
-cwppZigiY3JlYXRlQ29udGV4dHVhbEZyYWdtZW50IiBpbiB3aW5kb3cuUmFuZ2UucHJvdG90eXBlKXJl
-dHVybiB0aGlzLkRXKGEsYixjLGQpCnQ9Vy5VOSgiPHRhYmxlPiIrSC5kKGIpKyI8L3RhYmxlPiIsYyxk
-KQpzPWRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKQpzLnRvU3RyaW5nCnQudG9TdHJpbmcK
-bmV3IFcuZTcocykuRlYoMCxuZXcgVy5lNyh0KSkKcmV0dXJuIHN9fQpXLkl2LnByb3RvdHlwZT17CnI2
-OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMscixxCmlmKCJjcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQi
-IGluIHdpbmRvdy5SYW5nZS5wcm90b3R5cGUpcmV0dXJuIHRoaXMuRFcoYSxiLGMsZCkKdD1kb2N1bWVu
-dApzPXQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpCnQ9Qy5JZS5yNih0LmNyZWF0ZUVsZW1lbnQoInRh
-YmxlIiksYixjLGQpCnQudG9TdHJpbmcKdD1uZXcgVy5lNyh0KQpyPXQuZ3I4KHQpCnIudG9TdHJpbmcK
-dD1uZXcgVy5lNyhyKQpxPXQuZ3I4KHQpCnMudG9TdHJpbmcKcS50b1N0cmluZwpuZXcgVy5lNyhzKS5G
-VigwLG5ldyBXLmU3KHEpKQpyZXR1cm4gc319ClcuV1AucHJvdG90eXBlPXsKcjY6ZnVuY3Rpb24oYSxi
-LGMsZCl7dmFyIHQscyxyCmlmKCJjcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQiIGluIHdpbmRvdy5SYW5n
-ZS5wcm90b3R5cGUpcmV0dXJuIHRoaXMuRFcoYSxiLGMsZCkKdD1kb2N1bWVudApzPXQuY3JlYXRlRG9j
-dW1lbnRGcmFnbWVudCgpCnQ9Qy5JZS5yNih0LmNyZWF0ZUVsZW1lbnQoInRhYmxlIiksYixjLGQpCnQu
-dG9TdHJpbmcKdD1uZXcgVy5lNyh0KQpyPXQuZ3I4KHQpCnMudG9TdHJpbmcKci50b1N0cmluZwpuZXcg
-Vy5lNyhzKS5GVigwLG5ldyBXLmU3KHIpKQpyZXR1cm4gc319ClcueVkucHJvdG90eXBlPXsKcGs6ZnVu
-Y3Rpb24oYSxiLGMpe3ZhciB0LHMKYS50ZXh0Q29udGVudD1udWxsCnQ9YS5jb250ZW50CnQudG9TdHJp
-bmcKSi5iVCh0KQpzPXRoaXMucjYoYSxiLG51bGwsYykKYS5jb250ZW50LmFwcGVuZENoaWxkKHMpfSwK
-WUM6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5wayhhLGIsbnVsbCl9LAokaXlZOjF9ClcudzYucHJv
-dG90eXBlPXt9ClcuSzUucHJvdG90eXBlPXsKUG86ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PVcuUDEoYS5v
-cGVuKGIsYykpCnJldHVybiB0fSwKZ21XOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxvY2F0aW9ufSwKJGlL
-NToxLAokaXY2OjF9ClcuQ20ucHJvdG90eXBlPXskaUNtOjF9ClcuQ1EucHJvdG90eXBlPXskaUNROjF9
-ClcudzQucHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXtyZXR1cm4iUmVjdGFuZ2xlICgiK0guZChhLmxl
-ZnQpKyIsICIrSC5kKGEudG9wKSsiKSAiK0guZChhLndpZHRoKSsiIHggIitILmQoYS5oZWlnaHQpfSwK
-RE46ZnVuY3Rpb24oYSxiKXtpZihiPT1udWxsKXJldHVybiExCnJldHVybiB1Lk8uYihiKSYmYS5sZWZ0
-PT1iLmxlZnQmJmEudG9wPT1iLnRvcCYmYS53aWR0aD09Yi53aWR0aCYmYS5oZWlnaHQ9PWIuaGVpZ2h0
-fSwKZ2lPOmZ1bmN0aW9uKGEpe3JldHVybiBXLnJFKEouaGYoYS5sZWZ0KSxKLmhmKGEudG9wKSxKLmhm
-KGEud2lkdGgpLEouaGYoYS5oZWlnaHQpKX19ClcucmgucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7
-cmV0dXJuIGEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIpe0guV1koYikKaWYoYj4+PjAhPT1ifHxiPj1h
-Lmxlbmd0aCl0aHJvdyBILmIoUC50KGIsYSxudWxsLG51bGwsbnVsbCkpCnJldHVybiBhW2JdfSwKWTpm
-dW5jdGlvbihhLGIsYyl7dS5BLmEoYykKdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBhc3NpZ24gZWxlbWVu
-dCBvZiBpbW11dGFibGUgTGlzdC4iKSl9LApFOmZ1bmN0aW9uKGEsYil7aWYoYjwwfHxiPj1hLmxlbmd0
-aClyZXR1cm4gSC5rKGEsYikKcmV0dXJuIGFbYl19LAokaWJROjEsCiRpWGo6MSwKJGljWDoxLAokaXpN
-OjF9ClcuY2YucHJvdG90eXBlPXsKSzpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAKdS5lQS5hKGIp
-CmZvcih0PXRoaXMuZ1YoKSxzPXQubGVuZ3RoLHI9dGhpcy5hLHE9MDtxPHQubGVuZ3RoO3QubGVuZ3Ro
-PT09c3x8KDAsSC5saykodCksKytxKXtwPXRbcV0KYi4kMihwLHIuZ2V0QXR0cmlidXRlKHApKX19LApn
-VjpmdW5jdGlvbigpe3ZhciB0LHMscixxLHA9dGhpcy5hLmF0dHJpYnV0ZXMsbz1ILlZNKFtdLHUucykK
-Zm9yKHQ9cC5sZW5ndGgscz11Lmg5LHI9MDtyPHQ7KytyKXtpZihyPj1wLmxlbmd0aClyZXR1cm4gSC5r
-KHAscikKcT1zLmEocFtyXSkKaWYocS5uYW1lc3BhY2VVUkk9PW51bGwpQy5ObS5pKG8scS5uYW1lKX1y
-ZXR1cm4gb319ClcuaTcucHJvdG90eXBlPXsKeDQ6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5oYXNB
-dHRyaWJ1dGUoYSl9LApxOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuYS5nZXRBdHRyaWJ1dGUoSC5j
-KGIpKX0sClk6ZnVuY3Rpb24oYSxiLGMpe3RoaXMuYS5zZXRBdHRyaWJ1dGUoYixjKX0sCmdBOmZ1bmN0
-aW9uKGEpe3JldHVybiB0aGlzLmdWKCkubGVuZ3RofX0KVy5TeS5wcm90b3R5cGU9ewp4NDpmdW5jdGlv
-bihhKXtyZXR1cm4gdGhpcy5hLmEuaGFzQXR0cmlidXRlKCJkYXRhLSIrdGhpcy5PKGEpKX0sCnE6ZnVu
-Y3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5hLmEuZ2V0QXR0cmlidXRlKCJkYXRhLSIrdGhpcy5PKEguYyhi
-KSkpfSwKWTpmdW5jdGlvbihhLGIsYyl7dGhpcy5hLmEuc2V0QXR0cmlidXRlKCJkYXRhLSIrdGhpcy5P
-KGIpLGMpfSwKSzpmdW5jdGlvbihhLGIpe3RoaXMuYS5LKDAsbmV3IFcuS1ModGhpcyx1LmVBLmEoYikp
-KX0sCmdWOmZ1bmN0aW9uKCl7dmFyIHQ9SC5WTShbXSx1LnMpCnRoaXMuYS5LKDAsbmV3IFcuQTModGhp
-cyx0KSkKcmV0dXJuIHR9LApnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5nVigpLmxlbmd0aH0sCms6
-ZnVuY3Rpb24oYSl7dmFyIHQscyxyPUguVk0oYS5zcGxpdCgiLSIpLHUucykKZm9yKHQ9MTt0PHIubGVu
-Z3RoOysrdCl7cz1yW3RdCmlmKHMubGVuZ3RoPjApQy5ObS5ZKHIsdCxzWzBdLnRvVXBwZXJDYXNlKCkr
-Si5LVihzLDEpKX1yZXR1cm4gQy5ObS56VihyLCIiKX0sCk86ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEs
-cApmb3IodD1hLmxlbmd0aCxzPTAscj0iIjtzPHQ7KytzKXtxPWFbc10KcD1xLnRvTG93ZXJDYXNlKCkK
-cj0ocSE9PXAmJnM+MD9yKyItIjpyKStwfXJldHVybiByLmNoYXJDb2RlQXQoMCk9PTA/cjpyfX0KVy5L
-Uy5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe2lmKEouclkoYSkubihhLCJkYXRhLSIpKXRoaXMu
-Yi4kMih0aGlzLmEuayhDLnhCLkcoYSw1KSksYil9LAokUzo4fQpXLkEzLnByb3RvdHlwZT17CiQyOmZ1
-bmN0aW9uKGEsYil7aWYoSi5yWShhKS5uKGEsImRhdGEtIikpQy5ObS5pKHRoaXMuYix0aGlzLmEuayhD
-LnhCLkcoYSw1KSkpfSwKJFM6OH0KVy5JNC5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKCl7dmFyIHQscyxy
-LHEscD1QLkxzKHUuTikKZm9yKHQ9dGhpcy5hLmNsYXNzTmFtZS5zcGxpdCgiICIpLHM9dC5sZW5ndGgs
-cj0wO3I8czsrK3Ipe3E9Si5UMCh0W3JdKQppZihxLmxlbmd0aCE9PTApcC5pKDAscSl9cmV0dXJuIHB9
-LApwOmZ1bmN0aW9uKGEpe3RoaXMuYS5jbGFzc05hbWU9dS5DLmEoYSkuelYoMCwiICIpfSwKZ0E6ZnVu
-Y3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5jbGFzc0xpc3QubGVuZ3RofSwKVjE6ZnVuY3Rpb24oYSl7dGhp
-cy5hLmNsYXNzTmFtZT0iIn0sCnRnOmZ1bmN0aW9uKGEsYil7dmFyIHQ9dGhpcy5hLmNsYXNzTGlzdC5j
-b250YWlucyhiKQpyZXR1cm4gdH0sCmk6ZnVuY3Rpb24oYSxiKXt2YXIgdD10aGlzLmEuY2xhc3NMaXN0
-LHM9dC5jb250YWlucyhiKQp0LmFkZChiKQpyZXR1cm4hc30sClI6ZnVuY3Rpb24oYSxiKXt2YXIgdD10
-aGlzLmEuY2xhc3NMaXN0LHM9dC5jb250YWlucyhiKQp0LnJlbW92ZShiKQpyZXR1cm4gc30sCkZWOmZ1
-bmN0aW9uKGEsYil7Vy5UTih0aGlzLmEsdS5YLmEoYikpfX0KVy5Gay5wcm90b3R5cGU9e30KVy5STy5w
-cm90b3R5cGU9e30KVy5ldS5wcm90b3R5cGU9e30KVy54Qy5wcm90b3R5cGU9e30KVy52Ti5wcm90b3R5
-cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLiQxKHUuQi5hKGEpKX0sCiRTOjI4fQpXLkpR
-LnByb3RvdHlwZT17CkNZOmZ1bmN0aW9uKGEpe3ZhciB0CmlmKCQub3IuYT09PTApe2Zvcih0PTA7dDwy
-NjI7Kyt0KSQub3IuWSgwLEMuY21bdF0sVy5wUygpKQpmb3IodD0wO3Q8MTI7Kyt0KSQub3IuWSgwLEMu
-QklbdF0sVy5WNCgpKX19LAppMDpmdW5jdGlvbihhKXtyZXR1cm4gJC5BTigpLnRnKDAsVy5yUyhhKSl9
-LApFYjpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9JC5vci5xKDAsSC5kKFcuclMoYSkpKyI6OiIrYikKaWYo
-dD09bnVsbCl0PSQub3IucSgwLCIqOjoiK2IpCmlmKHQ9PW51bGwpcmV0dXJuITEKcmV0dXJuIEguRTko
-dC4kNChhLGIsYyx0aGlzKSl9LAokaWtGOjF9ClcuR20ucHJvdG90eXBlPXsKZ2t6OmZ1bmN0aW9uKGEp
-e3JldHVybiBuZXcgVy5XOShhLHRoaXMuZ0EoYSksSC5xKGEpLkMoIlc5PEdtLkU+IikpfX0KVy52RC5w
-cm90b3R5cGU9ewppMDpmdW5jdGlvbihhKXtyZXR1cm4gQy5ObS5Wcih0aGlzLmEsbmV3IFcuVXYoYSkp
-fSwKRWI6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBDLk5tLlZyKHRoaXMuYSxuZXcgVy5FZyhhLGIsYykp
-fSwKJGlrRjoxfQpXLlV2LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB1LmUuYShhKS5p
-MCh0aGlzLmEpfSwKJFM6MTV9ClcuRWcucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHUu
-ZS5hKGEpLkViKHRoaXMuYSx0aGlzLmIsdGhpcy5jKX0sCiRTOjE1fQpXLm02LnByb3RvdHlwZT17CkNZ
-OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMscgp0aGlzLmEuRlYoMCxjKQp0PWIuZXYoMCxuZXcgVy5F
-bygpKQpzPWIuZXYoMCxuZXcgVy5XaygpKQp0aGlzLmIuRlYoMCx0KQpyPXRoaXMuYwpyLkZWKDAsQy54
-RCkKci5GVigwLHMpfSwKaTA6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS50ZygwLFcuclMoYSkpfSwK
-RWI6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PXRoaXMscz1XLnJTKGEpLHI9dC5jCmlmKHIudGcoMCxILmQo
-cykrIjo6IitiKSlyZXR1cm4gdC5kLkR0KGMpCmVsc2UgaWYoci50ZygwLCIqOjoiK2IpKXJldHVybiB0
-LmQuRHQoYykKZWxzZXtyPXQuYgppZihyLnRnKDAsSC5kKHMpKyI6OiIrYikpcmV0dXJuITAKZWxzZSBp
-ZihyLnRnKDAsIio6OiIrYikpcmV0dXJuITAKZWxzZSBpZihyLnRnKDAsSC5kKHMpKyI6OioiKSlyZXR1
-cm4hMAplbHNlIGlmKHIudGcoMCwiKjo6KiIpKXJldHVybiEwfXJldHVybiExfSwKJGlrRjoxfQpXLkVv
-LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiFDLk5tLnRnKEMuQkksSC5jKGEpKX0sCiRT
-Ojd9ClcuV2sucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIEMuTm0udGcoQy5CSSxILmMo
-YSkpfSwKJFM6N30KVy5jdC5wcm90b3R5cGU9ewpFYjpmdW5jdGlvbihhLGIsYyl7aWYodGhpcy5qRihh
-LGIsYykpcmV0dXJuITAKaWYoYj09PSJ0ZW1wbGF0ZSImJmM9PT0iIilyZXR1cm4hMAppZihhLmdldEF0
-dHJpYnV0ZSgidGVtcGxhdGUiKT09PSIiKXJldHVybiB0aGlzLmUudGcoMCxiKQpyZXR1cm4hMX19Clcu
-SUEucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIlRFTVBMQVRFOjoiK0guZChILmMoYSkp
-fSwKJFM6NH0KVy5Pdy5wcm90b3R5cGU9ewppMDpmdW5jdGlvbihhKXt2YXIgdAppZih1LmV3LmIoYSkp
-cmV0dXJuITEKdD11Lmc3LmIoYSkKaWYodCYmVy5yUyhhKT09PSJmb3JlaWduT2JqZWN0IilyZXR1cm4h
-MQppZih0KXJldHVybiEwCnJldHVybiExfSwKRWI6ZnVuY3Rpb24oYSxiLGMpe2lmKGI9PT0iaXMifHxD
-LnhCLm4oYiwib24iKSlyZXR1cm4hMQpyZXR1cm4gdGhpcy5pMChhKX0sCiRpa0Y6MX0KVy5XOS5wcm90
-b3R5cGU9ewpGOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcyxzPXQuYysxLHI9dC5iCmlmKHM8cil7dC5zTShK
-Lng5KHQuYSxzKSkKdC5jPXMKcmV0dXJuITB9dC5zTShudWxsKQp0LmM9cgpyZXR1cm4hMX0sCmdsOmZ1
-bmN0aW9uKCl7cmV0dXJuIHRoaXMuZH0sCnNNOmZ1bmN0aW9uKGEpe3RoaXMuZD10aGlzLiR0aS5jLmEo
-YSl9LAokaUFuOjF9ClcuZFcucHJvdG90eXBlPXsKZ21XOmZ1bmN0aW9uKGEpe3JldHVybiBXLkhIKHRo
-aXMuYS5sb2NhdGlvbil9LAokaUQwOjEsCiRpdjY6MX0KVy5GYi5wcm90b3R5cGU9e30KVy5rRi5wcm90
-b3R5cGU9e30KVy5tay5wcm90b3R5cGU9eyRpeTA6MX0KVy5Lby5wcm90b3R5cGU9ewpQbjpmdW5jdGlv
-bihhKXt2YXIgdD10aGlzLHM9bmV3IFcuZm0odCkKdC5iPSExCnMuJDIoYSxudWxsKQpmb3IoO3QuYjsp
-e3QuYj0hMQpzLiQyKGEsbnVsbCl9fSwKRVA6ZnVuY3Rpb24oYSxiKXt2YXIgdD10aGlzLmI9ITAKaWYo
-YiE9bnVsbD9iIT09YS5wYXJlbnROb2RlOnQpSi5MdChhKQplbHNlIGIucmVtb3ZlQ2hpbGQoYSl9LApJ
-NDpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAsbz0hMCxuPW51bGwsbT1udWxsCnRyeXtuPUouaWco
-YSkKbT1uLmEuZ2V0QXR0cmlidXRlKCJpcyIpCnUuaC5hKGEpCnQ9ZnVuY3Rpb24oYyl7aWYoIShjLmF0
-dHJpYnV0ZXMgaW5zdGFuY2VvZiBOYW1lZE5vZGVNYXApKXJldHVybiB0cnVlCmlmKGMuaWQ9PSdsYXN0
-Q2hpbGQnfHxjLm5hbWU9PSdsYXN0Q2hpbGQnfHxjLmlkPT0ncHJldmlvdXNTaWJsaW5nJ3x8Yy5uYW1l
-PT0ncHJldmlvdXNTaWJsaW5nJ3x8Yy5pZD09J2NoaWxkcmVuJ3x8Yy5uYW1lPT0nY2hpbGRyZW4nKXJl
-dHVybiB0cnVlCnZhciBsPWMuY2hpbGROb2RlcwppZihjLmxhc3RDaGlsZCYmYy5sYXN0Q2hpbGQhPT1s
-W2wubGVuZ3RoLTFdKXJldHVybiB0cnVlCmlmKGMuY2hpbGRyZW4paWYoIShjLmNoaWxkcmVuIGluc3Rh
-bmNlb2YgSFRNTENvbGxlY3Rpb258fGMuY2hpbGRyZW4gaW5zdGFuY2VvZiBOb2RlTGlzdCkpcmV0dXJu
-IHRydWUKdmFyIGs9MAppZihjLmNoaWxkcmVuKWs9Yy5jaGlsZHJlbi5sZW5ndGgKZm9yKHZhciBqPTA7
-ajxrO2orKyl7dmFyIGk9Yy5jaGlsZHJlbltqXQppZihpLmlkPT0nYXR0cmlidXRlcyd8fGkubmFtZT09
-J2F0dHJpYnV0ZXMnfHxpLmlkPT0nbGFzdENoaWxkJ3x8aS5uYW1lPT0nbGFzdENoaWxkJ3x8aS5pZD09
-J3ByZXZpb3VzU2libGluZyd8fGkubmFtZT09J3ByZXZpb3VzU2libGluZyd8fGkuaWQ9PSdjaGlsZHJl
-bid8fGkubmFtZT09J2NoaWxkcmVuJylyZXR1cm4gdHJ1ZX1yZXR1cm4gZmFsc2V9KGEpCm89SC5vVCh0
-KT8hMDohKGEuYXR0cmlidXRlcyBpbnN0YW5jZW9mIE5hbWVkTm9kZU1hcCl9Y2F0Y2gocSl7SC5SdShx
-KX1zPSJlbGVtZW50IHVucHJpbnRhYmxlIgp0cnl7cz1KLkFjKGEpfWNhdGNoKHEpe0guUnUocSl9dHJ5
-e3I9Vy5yUyhhKQp0aGlzLmtSKHUuaC5hKGEpLGIsbyxzLHIsdS5HLmEobiksSC5jKG0pKX1jYXRjaChx
-KXtpZihILlJ1KHEpIGluc3RhbmNlb2YgUC5BVCl0aHJvdyBxCmVsc2V7dGhpcy5FUChhLGIpCndpbmRv
-dwpwPSJSZW1vdmluZyBjb3JydXB0ZWQgZWxlbWVudCAiK0guZChzKQppZih0eXBlb2YgY29uc29sZSE9
-InVuZGVmaW5lZCIpd2luZG93LmNvbnNvbGUud2FybihwKX19fSwKa1I6ZnVuY3Rpb24oYSxiLGMsZCxl
-LGYsZyl7dmFyIHQscyxyLHEscCxvLG49dGhpcwppZihjKXtuLkVQKGEsYikKd2luZG93CnQ9IlJlbW92
-aW5nIGVsZW1lbnQgZHVlIHRvIGNvcnJ1cHRlZCBhdHRyaWJ1dGVzIG9uIDwiK2QrIj4iCmlmKHR5cGVv
-ZiBjb25zb2xlIT0idW5kZWZpbmVkIil3aW5kb3cuY29uc29sZS53YXJuKHQpCnJldHVybn1pZighbi5h
-LmkwKGEpKXtuLkVQKGEsYikKd2luZG93CnQ9IlJlbW92aW5nIGRpc2FsbG93ZWQgZWxlbWVudCA8IitI
-LmQoZSkrIj4gZnJvbSAiK0guZChiKQppZih0eXBlb2YgY29uc29sZSE9InVuZGVmaW5lZCIpd2luZG93
-LmNvbnNvbGUud2Fybih0KQpyZXR1cm59aWYoZyE9bnVsbClpZighbi5hLkViKGEsImlzIixnKSl7bi5F
-UChhLGIpCndpbmRvdwp0PSJSZW1vdmluZyBkaXNhbGxvd2VkIHR5cGUgZXh0ZW5zaW9uIDwiK0guZChl
-KSsnIGlzPSInK2crJyI+JwppZih0eXBlb2YgY29uc29sZSE9InVuZGVmaW5lZCIpd2luZG93LmNvbnNv
-bGUud2Fybih0KQpyZXR1cm59dD1mLmdWKCkKcz1ILlZNKHQuc2xpY2UoMCksSC50Nih0KS5DKCJqZDwx
-PiIpKQpmb3Iocj1mLmdWKCkubGVuZ3RoLTEsdD1mLmE7cj49MDstLXIpe2lmKHI+PXMubGVuZ3RoKXJl
-dHVybiBILmsocyxyKQpxPXNbcl0KcD1uLmEKbz1KLmNIKHEpCkguYyhxKQppZighcC5FYihhLG8sdC5n
-ZXRBdHRyaWJ1dGUocSkpKXt3aW5kb3cKcD0iUmVtb3ZpbmcgZGlzYWxsb3dlZCBhdHRyaWJ1dGUgPCIr
-SC5kKGUpKyIgIitxKyc9IicrSC5kKHQuZ2V0QXR0cmlidXRlKHEpKSsnIj4nCmlmKHR5cGVvZiBjb25z
+bCl7bj1wLmIKaWYoMD49bi5sZW5ndGgpcmV0dXJuIEguT0gobiwwKQp0PXAuYQpuPW5bMF0rMQpzPUMu
+eEIuWFUodCwiPyIsbikKcj10Lmxlbmd0aAppZihzPj0wKXtxPVAuUEkodCxzKzEscixDLlZDLCExKQpy
+PXN9ZWxzZSBxPW8Kbj1wLmM9bmV3IFAucWUoImRhdGEiLCIiLG8sbyxQLlBJKHQsbixyLEMuV2QsITEp
+LHEsbyl9cmV0dXJuIG59LAp3OmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcy5iCmlmKDA+PXMubGVuZ3Ro
+KXJldHVybiBILk9IKHMsMCkKdD10aGlzLmEKcmV0dXJuIHNbMF09PT0tMT8iZGF0YToiK3Q6dH19ClAu
+cTMucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBVaW50OEFycmF5KDk2KX0sCiRT
+OjIzfQpQLnlJLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHQ9dGhpcy5hCmlmKGE+PXQu
+bGVuZ3RoKXJldHVybiBILk9IKHQsYSkKdD10W2FdCkouQ00odCwwLDk2LGIpCnJldHVybiB0fSwKJFM6
+MjR9ClAuYzYucHJvdG90eXBlPXsKJDM6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxCmZvcih0PWIu
+bGVuZ3RoLHM9YS5sZW5ndGgscj0wO3I8dDsrK3Ipe3E9Qy54Qi5XKGIscileOTYKaWYocT49cylyZXR1
+cm4gSC5PSChhLHEpCmFbcV09Y319fQpQLnFkLnByb3RvdHlwZT17CiQzOmZ1bmN0aW9uKGEsYixjKXt2
+YXIgdCxzLHIscQpmb3IodD1DLnhCLlcoYiwwKSxzPUMueEIuVyhiLDEpLHI9YS5sZW5ndGg7dDw9czsr
+K3Qpe3E9KHReOTYpPj4+MAppZihxPj1yKXJldHVybiBILk9IKGEscSkKYVtxXT1jfX19ClAuVWYucHJv
+dG90eXBlPXsKZ2NqOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYz4wfSwKZ3hBOmZ1bmN0aW9uKCl7cmV0
+dXJuIHRoaXMuYz4wJiZ0aGlzLmQrMTx0aGlzLmV9LApnUUQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5m
+PHRoaXMucn0sCmdaODpmdW5jdGlvbigpe3JldHVybiB0aGlzLnI8dGhpcy5hLmxlbmd0aH0sCmdOdzpm
+dW5jdGlvbigpe3JldHVybiB0aGlzLmI9PT00JiZDLnhCLm4odGhpcy5hLCJmaWxlIil9LApndmg6ZnVu
+Y3Rpb24oKXtyZXR1cm4gdGhpcy5iPT09NCYmQy54Qi5uKHRoaXMuYSwiaHR0cCIpfSwKZ1JlOmZ1bmN0
+aW9uKCl7cmV0dXJuIHRoaXMuYj09PTUmJkMueEIubih0aGlzLmEsImh0dHBzIil9LApndFQ6ZnVuY3Rp
+b24oKXtyZXR1cm4gQy54Qi5RaSh0aGlzLmEsIi8iLHRoaXMuZSl9LApnRmk6ZnVuY3Rpb24oKXt2YXIg
+dD10aGlzLngKcmV0dXJuIHQ9PW51bGw/dGhpcy54PXRoaXMuVTIoKTp0fSwKVTI6ZnVuY3Rpb24oKXt2
+YXIgdD10aGlzLHM9dC5iCmlmKHM8PTApcmV0dXJuIiIKaWYodC5ndmgoKSlyZXR1cm4iaHR0cCIKaWYo
+dC5nUmUoKSlyZXR1cm4iaHR0cHMiCmlmKHQuZ053KCkpcmV0dXJuImZpbGUiCmlmKHM9PT03JiZDLnhC
+Lm4odC5hLCJwYWNrYWdlIikpcmV0dXJuInBhY2thZ2UiCnJldHVybiBDLnhCLk5qKHQuYSwwLHMpfSwK
+Z2t1OmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5jLHM9dGhpcy5iKzMKcmV0dXJuIHQ+cz9DLnhCLk5qKHRo
+aXMuYSxzLHQtMSk6IiJ9LApnSmY6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5jCnJldHVybiB0PjA/Qy54
+Qi5Oaih0aGlzLmEsdCx0aGlzLmQpOiIifSwKZ3RwOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMKaWYodC5n
+eEEoKSlyZXR1cm4gUC5RQShDLnhCLk5qKHQuYSx0LmQrMSx0LmUpLG51bGwpCmlmKHQuZ3ZoKCkpcmV0
+dXJuIDgwCmlmKHQuZ1JlKCkpcmV0dXJuIDQ0MwpyZXR1cm4gMH0sCmdJaTpmdW5jdGlvbihhKXtyZXR1
+cm4gQy54Qi5Oaih0aGlzLmEsdGhpcy5lLHRoaXMuZil9LApndFA6ZnVuY3Rpb24oKXt2YXIgdD10aGlz
+LmYscz10aGlzLnIKcmV0dXJuIHQ8cz9DLnhCLk5qKHRoaXMuYSx0KzEscyk6IiJ9LApnS2E6ZnVuY3Rp
+b24oKXt2YXIgdD10aGlzLnIscz10aGlzLmEKcmV0dXJuIHQ8cy5sZW5ndGg/Qy54Qi5HKHMsdCsxKToi
+In0sCmdGajpmdW5jdGlvbigpe3ZhciB0LHMscj10aGlzLmUscT10aGlzLmYscD10aGlzLmEKaWYoQy54
+Qi5RaShwLCIvIixyKSkrK3IKaWYocj09PXEpcmV0dXJuIEMueEQKdD1ILlZNKFtdLHUucykKZm9yKHM9
+cjtzPHE7KytzKWlmKEMueEIubShwLHMpPT09NDcpe0MuTm0uaSh0LEMueEIuTmoocCxyLHMpKQpyPXMr
+MX1DLk5tLmkodCxDLnhCLk5qKHAscixxKSkKcmV0dXJuIFAuQUYodCx1Lk4pfSwKZ2hZOmZ1bmN0aW9u
+KCl7aWYodGhpcy5mPj10aGlzLnIpcmV0dXJuIEMuV08KcmV0dXJuIG5ldyBQLkdqKFAuV1godGhpcy5n
+dFAoKSksdS5kdyl9LAprWDpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmQrMQpyZXR1cm4gdCthLmxlbmd0
+aD09PXRoaXMuZSYmQy54Qi5RaSh0aGlzLmEsYSx0KX0sCk45OmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcyxz
+PXQucixyPXQuYQppZihzPj1yLmxlbmd0aClyZXR1cm4gdApyZXR1cm4gbmV3IFAuVWYoQy54Qi5Oaihy
+LDAscyksdC5iLHQuYyx0LmQsdC5lLHQuZixzLHQueCl9LApubTpmdW5jdGlvbihhLGIpe3ZhciB0LHMs
+cixxLHAsbyxuLG0sbCxrLGo9dGhpcyxpPW51bGwKdS5VLmEobnVsbCkKdS5jOS5hKGIpCnQ9ai5nRmko
+KQpzPXQ9PT0iZmlsZSIKcj1qLmMKcT1yPjA/Qy54Qi5OaihqLmEsai5iKzMscik6IiIKcD1qLmd4QSgp
+P2ouZ3RwKGopOmkKcj1qLmMKaWYocj4wKW89Qy54Qi5OaihqLmEscixqLmQpCmVsc2Ugbz1xLmxlbmd0
+aCE9PTB8fHAhPW51bGx8fHM/IiI6aQpyPWouYQpuPUMueEIuTmoocixqLmUsai5mKQppZighcyltPW8h
+PW51bGwmJm4ubGVuZ3RoIT09MAplbHNlIG09ITAKaWYobSYmIUMueEIubihuLCIvIikpbj0iLyIrbgps
+PVAubGUoaSwwLDAsYikKbT1qLnIKaz1tPHIubGVuZ3RoP0MueEIuRyhyLG0rMSk6aQpyZXR1cm4gbmV3
+IFAuRG4odCxxLG8scCxuLGwsayl9LApaSTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5tUyhQLmhLKGEp
+KX0sCm1TOmZ1bmN0aW9uKGEpe2lmKGEgaW5zdGFuY2VvZiBQLlVmKXJldHVybiB0aGlzLnUxKHRoaXMs
+YSkKcmV0dXJuIHRoaXMudnMoKS5tUyhhKX0sCnUxOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxv
+LG4sbSxsLGssaixpLGg9Yi5iCmlmKGg+MClyZXR1cm4gYgp0PWIuYwppZih0PjApe3M9YS5iCmlmKHM8
+PTApcmV0dXJuIGIKaWYoYS5nTncoKSlyPWIuZSE9PWIuZgplbHNlIGlmKGEuZ3ZoKCkpcj0hYi5rWCgi
+ODAiKQplbHNlIHI9IWEuZ1JlKCl8fCFiLmtYKCI0NDMiKQppZihyKXtxPXMrMQpyZXR1cm4gbmV3IFAu
+VWYoQy54Qi5OaihhLmEsMCxxKStDLnhCLkcoYi5hLGgrMSkscyx0K3EsYi5kK3EsYi5lK3EsYi5mK3Es
+Yi5yK3EsYS54KX1lbHNlIHJldHVybiB0aGlzLnZzKCkubVMoYil9cD1iLmUKaD1iLmYKaWYocD09PWgp
+e3Q9Yi5yCmlmKGg8dCl7cz1hLmYKcT1zLWgKcmV0dXJuIG5ldyBQLlVmKEMueEIuTmooYS5hLDAscykr
+Qy54Qi5HKGIuYSxoKSxhLmIsYS5jLGEuZCxhLmUsaCtxLHQrcSxhLngpfWg9Yi5hCmlmKHQ8aC5sZW5n
+dGgpe3M9YS5yCnJldHVybiBuZXcgUC5VZihDLnhCLk5qKGEuYSwwLHMpK0MueEIuRyhoLHQpLGEuYixh
+LmMsYS5kLGEuZSxhLmYsdCsocy10KSxhLngpfXJldHVybiBhLk45KCl9dD1iLmEKaWYoQy54Qi5RaSh0
+LCIvIixwKSl7cz1hLmUKcT1zLXAKcmV0dXJuIG5ldyBQLlVmKEMueEIuTmooYS5hLDAscykrQy54Qi5H
+KHQscCksYS5iLGEuYyxhLmQscyxoK3EsYi5yK3EsYS54KX1vPWEuZQpuPWEuZgppZihvPT09biYmYS5j
+PjApe2Zvcig7Qy54Qi5RaSh0LCIuLi8iLHApOylwKz0zCnE9by1wKzEKcmV0dXJuIG5ldyBQLlVmKEMu
+eEIuTmooYS5hLDAsbykrIi8iK0MueEIuRyh0LHApLGEuYixhLmMsYS5kLG8saCtxLGIucitxLGEueCl9
+bT1hLmEKZm9yKGw9bztDLnhCLlFpKG0sIi4uLyIsbCk7KWwrPTMKaz0wCndoaWxlKCEwKXtqPXArMwpp
+ZighKGo8PWgmJkMueEIuUWkodCwiLi4vIixwKSkpYnJlYWs7KytrCnA9an1mb3IoaT0iIjtuPmw7KXst
+LW4KaWYoQy54Qi5tKG0sbik9PT00Nyl7aWYoaz09PTApe2k9Ii8iCmJyZWFrfS0tawppPSIvIn19aWYo
+bj09PWwmJmEuYjw9MCYmIUMueEIuUWkobSwiLyIsbykpe3AtPWsqMwppPSIifXE9bi1wK2kubGVuZ3Ro
+CnJldHVybiBuZXcgUC5VZihDLnhCLk5qKG0sMCxuKStpK0MueEIuRyh0LHApLGEuYixhLmMsYS5kLG8s
+aCtxLGIucitxLGEueCl9LAp0NDpmdW5jdGlvbigpe3ZhciB0LHMscixxPXRoaXMKaWYocS5iPj0wJiYh
+cS5nTncoKSl0aHJvdyBILmIoUC5MNCgiQ2Fubm90IGV4dHJhY3QgYSBmaWxlIHBhdGggZnJvbSBhICIr
+cS5nRmkoKSsiIFVSSSIpKQp0PXEuZgpzPXEuYQppZih0PHMubGVuZ3RoKXtpZih0PHEucil0aHJvdyBI
+LmIoUC5MNCgiQ2Fubm90IGV4dHJhY3QgYSBmaWxlIHBhdGggZnJvbSBhIFVSSSB3aXRoIGEgcXVlcnkg
+Y29tcG9uZW50IikpCnRocm93IEguYihQLkw0KCJDYW5ub3QgZXh0cmFjdCBhIGZpbGUgcGF0aCBmcm9t
+IGEgVVJJIHdpdGggYSBmcmFnbWVudCBjb21wb25lbnQiKSl9cj0kLndRKCkKaWYoSC5vVChyKSl0PVAu
+bW4ocSkKZWxzZXtpZihxLmM8cS5kKUgudmgoUC5MNCgiQ2Fubm90IGV4dHJhY3QgYSBub24tV2luZG93
+cyBmaWxlIHBhdGggZnJvbSBhIGZpbGUgVVJJIHdpdGggYW4gYXV0aG9yaXR5IikpCnQ9Qy54Qi5Oaihz
+LHEuZSx0KX1yZXR1cm4gdH0sCmdpTzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLnkKcmV0dXJuIHQ9PW51
+bGw/dGhpcy55PUMueEIuZ2lPKHRoaXMuYSk6dH0sCkROOmZ1bmN0aW9uKGEsYil7aWYoYj09bnVsbCly
+ZXR1cm4hMQppZih0aGlzPT09YilyZXR1cm4hMApyZXR1cm4gdS5kRC5iKGIpJiZ0aGlzLmE9PT1iLnco
+MCl9LAp2czpmdW5jdGlvbigpe3ZhciB0PXRoaXMscz1udWxsLHI9dC5nRmkoKSxxPXQuZ2t1KCkscD10
+LmM+MD90LmdKZih0KTpzLG89dC5neEEoKT90Lmd0cCh0KTpzLG49dC5hLG09dC5mLGw9Qy54Qi5Oaihu
+LHQuZSxtKSxrPXQucgptPW08az90Lmd0UCgpOnMKcmV0dXJuIG5ldyBQLkRuKHIscSxwLG8sbCxtLGs8
+bi5sZW5ndGg/dC5nS2EoKTpzKX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYX0sCiRpaUQ6MX0K
+UC5xZS5wcm90b3R5cGU9e30KVy5xRS5wcm90b3R5cGU9e30KVy5HaC5wcm90b3R5cGU9ewp3OmZ1bmN0
+aW9uKGEpe3JldHVybiBTdHJpbmcoYSl9LAokaUdoOjF9ClcuZlkucHJvdG90eXBlPXsKdzpmdW5jdGlv
+bihhKXtyZXR1cm4gU3RyaW5nKGEpfX0KVy5uQi5wcm90b3R5cGU9eyRpbkI6MX0KVy5Bei5wcm90b3R5
+cGU9eyRpQXo6MX0KVy5RUC5wcm90b3R5cGU9eyRpUVA6MX0KVy5ueC5wcm90b3R5cGU9ewpnQTpmdW5j
+dGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9fQpXLm9KLnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3Jl
+dHVybiBhLmxlbmd0aH19ClcuaWQucHJvdG90eXBlPXt9ClcuUUYucHJvdG90eXBlPXt9ClcuTmgucHJv
+dG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4gU3RyaW5nKGEpfX0KVy5hZS5wcm90b3R5cGU9ewpE
+YzpmdW5jdGlvbihhLGIpe3JldHVybiBhLmNyZWF0ZUhUTUxEb2N1bWVudChiKX19ClcuSUIucHJvdG90
+eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iUmVjdGFuZ2xlICgiK0guRWooYS5sZWZ0KSsiLCAiK0gu
+RWooYS50b3ApKyIpICIrSC5FaihhLndpZHRoKSsiIHggIitILkVqKGEuaGVpZ2h0KX0sCkROOmZ1bmN0
+aW9uKGEsYil7aWYoYj09bnVsbClyZXR1cm4hMQpyZXR1cm4gdS5xLmIoYikmJmEubGVmdD09PWIubGVm
+dCYmYS50b3A9PT1iLnRvcCYmYS53aWR0aD09PWIud2lkdGgmJmEuaGVpZ2h0PT09Yi5oZWlnaHR9LApn
+aU86ZnVuY3Rpb24oYSl7cmV0dXJuIFcuckUoQy5DRC5naU8oYS5sZWZ0KSxDLkNELmdpTyhhLnRvcCks
+Qy5DRC5naU8oYS53aWR0aCksQy5DRC5naU8oYS5oZWlnaHQpKX0sCiRpdG46MX0KVy5uNy5wcm90b3R5
+cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9fQpXLnd6LnByb3RvdHlwZT17CmdBOmZ1
+bmN0aW9uKGEpe3JldHVybiB0aGlzLmEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIpe3ZhciB0CkgudVAo
+YikKdD10aGlzLmEKaWYoYjwwfHxiPj10Lmxlbmd0aClyZXR1cm4gSC5PSCh0LGIpCnJldHVybiB0aGlz
+LiR0aS5jLmEodFtiXSl9LApZOmZ1bmN0aW9uKGEsYixjKXt0aGlzLiR0aS5jLmEoYykKdGhyb3cgSC5i
+KFAuTDQoIkNhbm5vdCBtb2RpZnkgbGlzdCIpKX19ClcuY3YucHJvdG90eXBlPXsKZ1FnOmZ1bmN0aW9u
+KGEpe3JldHVybiBuZXcgVy5pNyhhKX0sCmdQOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgVy5JNChhKX0s
+CnNQOmZ1bmN0aW9uKGEsYil7dmFyIHQKdS5RLmEoYikKdD10aGlzLmdQKGEpCnQuVjEoMCkKdC5GVigw
+LGIpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gYS5sb2NhbE5hbWV9LApGRjpmdW5jdGlvbihhKXt2YXIg
+dD0hIWEuc2Nyb2xsSW50b1ZpZXdJZk5lZWRlZAppZih0KWEuc2Nyb2xsSW50b1ZpZXdJZk5lZWRlZCgp
+CmVsc2UgYS5zY3JvbGxJbnRvVmlldygpfSwKbno6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgdCxzPXRo
+aXMucjYoYSxjLGQsZSkKc3dpdGNoKGIudG9Mb3dlckNhc2UoKSl7Y2FzZSJiZWZvcmViZWdpbiI6dD1h
+LnBhcmVudE5vZGUKdC50b1N0cmluZwpKLkVoKHQscyxhKQpicmVhawpjYXNlImFmdGVyYmVnaW4iOnQ9
+YS5jaGlsZE5vZGVzCnRoaXMubUsoYSxzLHQubGVuZ3RoPjA/dFswXTpudWxsKQpicmVhawpjYXNlImJl
+Zm9yZWVuZCI6YS5hcHBlbmRDaGlsZChzKQpicmVhawpjYXNlImFmdGVyZW5kIjp0PWEucGFyZW50Tm9k
+ZQp0LnRvU3RyaW5nCkouRWgodCxzLGEubmV4dFNpYmxpbmcpCmJyZWFrCmRlZmF1bHQ6SC52aChQLnhZ
+KCJJbnZhbGlkIHBvc2l0aW9uICIrYikpfX0sCnI2OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMscixx
+CmlmKGM9PW51bGwpe2lmKGQ9PW51bGwpe3Q9JC5sdAppZih0PT1udWxsKXt0PUguVk0oW10sdS5wKQpz
+PW5ldyBXLnZEKHQpCkMuTm0uaSh0LFcuVHcobnVsbCkpCkMuTm0uaSh0LFcuQmwoKSkKJC5sdD1zCmQ9
+c31lbHNlIGQ9dH10PSQuRVUKaWYodD09bnVsbCl7dD1uZXcgVy5LbyhkKQokLkVVPXQKYz10fWVsc2V7
+dC5hPWQKYz10fX1lbHNlIGlmKGQhPW51bGwpdGhyb3cgSC5iKFAueFkoInZhbGlkYXRvciBjYW4gb25s
+eSBiZSBwYXNzZWQgaWYgdHJlZVNhbml0aXplciBpcyBudWxsIikpCmlmKCQueG89PW51bGwpe3Q9ZG9j
+dW1lbnQKcz1DLm1ILkRjKHQuaW1wbGVtZW50YXRpb24sIiIpCiQueG89cwokLkJPPXMuY3JlYXRlUmFu
+Z2UoKQpzPSQueG8uY3JlYXRlRWxlbWVudCgiYmFzZSIpCnUuY1IuYShzKQpzLmhyZWY9dC5iYXNlVVJJ
+CiQueG8uaGVhZC5hcHBlbmRDaGlsZChzKX10PSQueG8KaWYodC5ib2R5PT1udWxsKXtzPXQuY3JlYXRl
+RWxlbWVudCgiYm9keSIpCkMuQlouc1hHKHQsdS5rLmEocykpfXQ9JC54bwppZih1LmsuYihhKSl7dD10
+LmJvZHkKdC50b1N0cmluZwpyPXR9ZWxzZXt0LnRvU3RyaW5nCnI9dC5jcmVhdGVFbGVtZW50KGEudGFn
+TmFtZSkKJC54by5ib2R5LmFwcGVuZENoaWxkKHIpfWlmKCJjcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQi
+IGluIHdpbmRvdy5SYW5nZS5wcm90b3R5cGUmJiFDLk5tLnRnKEMuU3EsYS50YWdOYW1lKSl7JC5CTy5z
+ZWxlY3ROb2RlQ29udGVudHMocikKcT0kLkJPLmNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudChiKX1lbHNl
+e0oud2YocixiKQpxPSQueG8uY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpCmZvcig7dD1yLmZpcnN0Q2hp
+bGQsdCE9bnVsbDspcS5hcHBlbmRDaGlsZCh0KX1pZihyIT09JC54by5ib2R5KUouTHQocikKYy5Qbihx
+KQpkb2N1bWVudC5hZG9wdE5vZGUocSkKcmV0dXJuIHF9LApBSDpmdW5jdGlvbihhLGIsYyl7cmV0dXJu
+IHRoaXMucjYoYSxiLGMsbnVsbCl9LApzaGY6ZnVuY3Rpb24oYSxiKXt0aGlzLllDKGEsYil9LApwazpm
+dW5jdGlvbihhLGIsYyl7dGhpcy5zYTQoYSxudWxsKQpiLnRvU3RyaW5nCmEuYXBwZW5kQ2hpbGQodGhp
+cy5yNihhLGIsbnVsbCxjKSl9LApZQzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLnBrKGEsYixudWxs
+KX0sCnNSTjpmdW5jdGlvbihhLGIpe2EuaW5uZXJIVE1MPWJ9LApnbnM6ZnVuY3Rpb24oYSl7cmV0dXJu
+IGEudGFnTmFtZX0sCmdWbDpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFcuZXUoYSwiY2xpY2siLCExLHUu
+Ryl9LAokaWN2OjF9ClcuQ3YucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHUuaC5iKHUu
+QS5hKGEpKX0sCiRTOjI1fQpXLmVhLnByb3RvdHlwZT17JGllYToxfQpXLkQwLnByb3RvdHlwZT17Ck9u
+OmZ1bmN0aW9uKGEsYixjLGQpe3UuYncuYShjKQppZihjIT1udWxsKXRoaXMudihhLGIsYyxkKX0sCkI6
+ZnVuY3Rpb24oYSxiLGMpe3JldHVybiB0aGlzLk9uKGEsYixjLG51bGwpfSwKdjpmdW5jdGlvbihhLGIs
+YyxkKXtyZXR1cm4gYS5hZGRFdmVudExpc3RlbmVyKGIsSC50Uih1LmJ3LmEoYyksMSksZCl9LAokaUQw
+OjF9ClcuVDUucHJvdG90eXBlPXskaVQ1OjF9ClcuaDQucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7
+cmV0dXJuIGEubGVuZ3RofX0KVy5ici5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5s
+ZW5ndGh9fQpXLlZiLnByb3RvdHlwZT17CnNYRzpmdW5jdGlvbihhLGIpe2EuYm9keT1ifX0KVy5mSi5w
+cm90b3R5cGU9ewplbzpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm4gYS5vcGVuKGIsYywhMCl9LAokaWZK
+OjF9ClcuYlUucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt0aGlzLmEuc2V0UmVxdWVzdEhlYWRl
+cihILmgoYSksSC5oKGIpKX0sCiRTOjd9ClcuaEgucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFy
+IHQscyxyLHEscAp1LmdaLmEoYSkKdD10aGlzLmEKcz10LnN0YXR1cwpyPXM+PTIwMCYmczwzMDAKcT1z
+PjMwNyYmczw0MDAKcz1yfHxzPT09MHx8cz09PTMwNHx8cQpwPXRoaXMuYgppZihzKXAuYU0oMCx0KQpl
+bHNlIHAucG0oYSl9LAokUzoyN30KVy53YS5wcm90b3R5cGU9e30KVy5TZy5wcm90b3R5cGU9eyRpU2c6
+MX0KVy51OC5wcm90b3R5cGU9ewpnRHI6ZnVuY3Rpb24oYSl7aWYoIm9yaWdpbiIgaW4gYSlyZXR1cm4g
+YS5vcmlnaW4KcmV0dXJuIGEucHJvdG9jb2wrIi8vIithLmhvc3R9LAp3OmZ1bmN0aW9uKGEpe3JldHVy
+biBTdHJpbmcoYSl9LAokaXU4OjF9ClcuT0sucHJvdG90eXBlPXskaU9LOjF9ClcuZTcucHJvdG90eXBl
+PXsKZ3I4OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYSxzPXQuY2hpbGROb2Rlcy5sZW5ndGgKaWYocz09
+PTApdGhyb3cgSC5iKFAuUFYoIk5vIGVsZW1lbnRzIikpCmlmKHM+MSl0aHJvdyBILmIoUC5QVigiTW9y
+ZSB0aGFuIG9uZSBlbGVtZW50IikpCnQ9dC5maXJzdENoaWxkCnQudG9TdHJpbmcKcmV0dXJuIHR9LApG
+VjpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAKdS5laC5hKGIpCnQ9Yi5hCnM9dGhpcy5hCmlmKHQh
+PT1zKWZvcihyPXQuY2hpbGROb2Rlcy5sZW5ndGgscT0wO3E8cjsrK3Epe3A9dC5maXJzdENoaWxkCnAu
+dG9TdHJpbmcKcy5hcHBlbmRDaGlsZChwKX1yZXR1cm59LApZOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxz
+CnUuQS5hKGMpCnQ9dGhpcy5hCnM9dC5jaGlsZE5vZGVzCmlmKGI8MHx8Yj49cy5sZW5ndGgpcmV0dXJu
+IEguT0gocyxiKQp0LnJlcGxhY2VDaGlsZChjLHNbYl0pfSwKZ2t6OmZ1bmN0aW9uKGEpe3ZhciB0PXRo
+aXMuYS5jaGlsZE5vZGVzCnJldHVybiBuZXcgVy5XOSh0LHQubGVuZ3RoLEgueih0KS5DKCJXOTxHbS5F
+PiIpKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEuY2hpbGROb2Rlcy5sZW5ndGh9LApxOmZ1
+bmN0aW9uKGEsYil7dmFyIHQKSC51UChiKQp0PXRoaXMuYS5jaGlsZE5vZGVzCmlmKGI8MHx8Yj49dC5s
+ZW5ndGgpcmV0dXJuIEguT0godCxiKQpyZXR1cm4gdFtiXX19ClcudUgucHJvdG90eXBlPXsKd2c6ZnVu
+Y3Rpb24oYSl7dmFyIHQ9YS5wYXJlbnROb2RlCmlmKHQhPW51bGwpdC5yZW1vdmVDaGlsZChhKX0sCkQ0
+OmZ1bmN0aW9uKGEpe3ZhciB0CmZvcig7dD1hLmZpcnN0Q2hpbGQsdCE9bnVsbDspYS5yZW1vdmVDaGls
+ZCh0KX0sCnc6ZnVuY3Rpb24oYSl7dmFyIHQ9YS5ub2RlVmFsdWUKcmV0dXJuIHQ9PW51bGw/dGhpcy5V
+KGEpOnR9LApzYTQ6ZnVuY3Rpb24oYSxiKXthLnRleHRDb250ZW50PWJ9LAptSzpmdW5jdGlvbihhLGIs
+Yyl7cmV0dXJuIGEuaW5zZXJ0QmVmb3JlKGIsYyl9LAokaXVIOjF9ClcuQkgucHJvdG90eXBlPXsKZ0E6
+ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIpe0gudVAoYikKaWYoYj4+
+PjAhPT1ifHxiPj1hLmxlbmd0aCl0aHJvdyBILmIoUC5DZihiLGEsbnVsbCxudWxsLG51bGwpKQpyZXR1
+cm4gYVtiXX0sClk6ZnVuY3Rpb24oYSxiLGMpe3UuQS5hKGMpCnRocm93IEguYihQLkw0KCJDYW5ub3Qg
+YXNzaWduIGVsZW1lbnQgb2YgaW1tdXRhYmxlIExpc3QuIikpfSwKRTpmdW5jdGlvbihhLGIpe2lmKGI8
+MHx8Yj49YS5sZW5ndGgpcmV0dXJuIEguT0goYSxiKQpyZXR1cm4gYVtiXX0sCiRpYlE6MSwKJGlYajox
+LAokaWNYOjEsCiRpek06MX0KVy5TTi5wcm90b3R5cGU9e30KVy5ldy5wcm90b3R5cGU9eyRpZXc6MX0K
+Vy5scC5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9fQpXLlRiLnByb3Rv
+dHlwZT17CnI2OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMKaWYoImNyZWF0ZUNvbnRleHR1YWxGcmFn
+bWVudCIgaW4gd2luZG93LlJhbmdlLnByb3RvdHlwZSlyZXR1cm4gdGhpcy5EVyhhLGIsYyxkKQp0PVcu
+VTkoIjx0YWJsZT4iK0guRWooYikrIjwvdGFibGU+IixjLGQpCnM9ZG9jdW1lbnQuY3JlYXRlRG9jdW1l
+bnRGcmFnbWVudCgpCnQudG9TdHJpbmcKbmV3IFcuZTcocykuRlYoMCxuZXcgVy5lNyh0KSkKcmV0dXJu
+IHN9fQpXLkl2LnByb3RvdHlwZT17CnI2OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMscixxCmlmKCJj
+cmVhdGVDb250ZXh0dWFsRnJhZ21lbnQiIGluIHdpbmRvdy5SYW5nZS5wcm90b3R5cGUpcmV0dXJuIHRo
+aXMuRFcoYSxiLGMsZCkKdD1kb2N1bWVudApzPXQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpCnQ9bmV3
+IFcuZTcoQy5JZS5yNih0LmNyZWF0ZUVsZW1lbnQoInRhYmxlIiksYixjLGQpKQpyPXQuZ3I4KHQpCnIu
+dG9TdHJpbmcKdD1uZXcgVy5lNyhyKQpxPXQuZ3I4KHQpCnEudG9TdHJpbmcKbmV3IFcuZTcocykuRlYo
+MCxuZXcgVy5lNyhxKSkKcmV0dXJuIHN9fQpXLldQLnByb3RvdHlwZT17CnI2OmZ1bmN0aW9uKGEsYixj
+LGQpe3ZhciB0LHMscgppZigiY3JlYXRlQ29udGV4dHVhbEZyYWdtZW50IiBpbiB3aW5kb3cuUmFuZ2Uu
+cHJvdG90eXBlKXJldHVybiB0aGlzLkRXKGEsYixjLGQpCnQ9ZG9jdW1lbnQKcz10LmNyZWF0ZURvY3Vt
+ZW50RnJhZ21lbnQoKQp0PW5ldyBXLmU3KEMuSWUucjYodC5jcmVhdGVFbGVtZW50KCJ0YWJsZSIpLGIs
+YyxkKSkKcj10LmdyOCh0KQpyLnRvU3RyaW5nCm5ldyBXLmU3KHMpLkZWKDAsbmV3IFcuZTcocikpCnJl
+dHVybiBzfX0KVy55WS5wcm90b3R5cGU9ewpwazpmdW5jdGlvbihhLGIsYyl7dmFyIHQKdGhpcy5zYTQo
+YSxudWxsKQpKLmJUKGEuY29udGVudCkKYi50b1N0cmluZwp0PXRoaXMucjYoYSxiLG51bGwsYykKYS5j
+b250ZW50LmFwcGVuZENoaWxkKHQpfSwKWUM6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5wayhhLGIs
+bnVsbCl9LAokaXlZOjF9ClcudzYucHJvdG90eXBlPXt9ClcuSzUucHJvdG90eXBlPXsKUG86ZnVuY3Rp
+b24oYSxiLGMpe3ZhciB0PVcuUDEoYS5vcGVuKGIsYykpCnJldHVybiB0fSwKZ21XOmZ1bmN0aW9uKGEp
+e3JldHVybiBhLmxvY2F0aW9ufSwKVXg6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gYS5hbGVydChiKX0sCnVz
+OmZ1bmN0aW9uKGEsYil7cmV0dXJuIGEuY29uZmlybShiKX0sCiRpSzU6MSwKJGl2NjoxfQpXLkNtLnBy
+b3RvdHlwZT17JGlDbToxfQpXLkNRLnByb3RvdHlwZT17JGlDUToxfQpXLnc0LnByb3RvdHlwZT17Cnc6
+ZnVuY3Rpb24oYSl7cmV0dXJuIlJlY3RhbmdsZSAoIitILkVqKGEubGVmdCkrIiwgIitILkVqKGEudG9w
+KSsiKSAiK0guRWooYS53aWR0aCkrIiB4ICIrSC5FaihhLmhlaWdodCl9LApETjpmdW5jdGlvbihhLGIp
+e2lmKGI9PW51bGwpcmV0dXJuITEKcmV0dXJuIHUucS5iKGIpJiZhLmxlZnQ9PT1iLmxlZnQmJmEudG9w
+PT09Yi50b3AmJmEud2lkdGg9PT1iLndpZHRoJiZhLmhlaWdodD09PWIuaGVpZ2h0fSwKZ2lPOmZ1bmN0
+aW9uKGEpe3JldHVybiBXLnJFKEMuQ0QuZ2lPKGEubGVmdCksQy5DRC5naU8oYS50b3ApLEMuQ0QuZ2lP
+KGEud2lkdGgpLEMuQ0QuZ2lPKGEuaGVpZ2h0KSl9fQpXLnJoLnByb3RvdHlwZT17CmdBOmZ1bmN0aW9u
+KGEpe3JldHVybiBhLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXtILnVQKGIpCmlmKGI+Pj4wIT09Ynx8
+Yj49YS5sZW5ndGgpdGhyb3cgSC5iKFAuQ2YoYixhLG51bGwsbnVsbCxudWxsKSkKcmV0dXJuIGFbYl19
+LApZOmZ1bmN0aW9uKGEsYixjKXt1LkEuYShjKQp0aHJvdyBILmIoUC5MNCgiQ2Fubm90IGFzc2lnbiBl
+bGVtZW50IG9mIGltbXV0YWJsZSBMaXN0LiIpKX0sCkU6ZnVuY3Rpb24oYSxiKXtpZihiPDB8fGI+PWEu
+bGVuZ3RoKXJldHVybiBILk9IKGEsYikKcmV0dXJuIGFbYl19LAokaWJROjEsCiRpWGo6MSwKJGljWDox
+LAokaXpNOjF9ClcuY2YucHJvdG90eXBlPXsKSzpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAKdS5l
+QS5hKGIpCmZvcih0PXRoaXMuZ1YoKSxzPXQubGVuZ3RoLHI9dGhpcy5hLHE9MDtxPHQubGVuZ3RoO3Qu
+bGVuZ3RoPT09c3x8KDAsSC5saykodCksKytxKXtwPXRbcV0KYi4kMihwLHIuZ2V0QXR0cmlidXRlKHAp
+KX19LApnVjpmdW5jdGlvbigpe3ZhciB0LHMscixxLHA9dGhpcy5hLmF0dHJpYnV0ZXMsbz1ILlZNKFtd
+LHUucykKZm9yKHQ9cC5sZW5ndGgscz11Lmg5LHI9MDtyPHQ7KytyKXtpZihyPj1wLmxlbmd0aClyZXR1
+cm4gSC5PSChwLHIpCnE9cy5hKHBbcl0pCmlmKHEubmFtZXNwYWNlVVJJPT1udWxsKUMuTm0uaShvLHEu
+bmFtZSl9cmV0dXJuIG99fQpXLmk3LnByb3RvdHlwZT17Cng0OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMu
+YS5oYXNBdHRyaWJ1dGUoYSkKcmV0dXJuIHR9LApxOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuYS5n
+ZXRBdHRyaWJ1dGUoSC5oKGIpKX0sClk6ZnVuY3Rpb24oYSxiLGMpe3RoaXMuYS5zZXRBdHRyaWJ1dGUo
+YixjKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmdWKCkubGVuZ3RofX0KVy5TeS5wcm90b3R5
+cGU9ewp4NDpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEuYS5oYXNBdHRyaWJ1dGUoImRhdGEtIit0aGlz
+Lk8oYSkpCnJldHVybiB0fSwKcTpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmEuYS5nZXRBdHRyaWJ1
+dGUoImRhdGEtIit0aGlzLk8oSC5oKGIpKSl9LApZOmZ1bmN0aW9uKGEsYixjKXt0aGlzLmEuYS5zZXRB
+dHRyaWJ1dGUoImRhdGEtIit0aGlzLk8oYiksYyl9LApLOmZ1bmN0aW9uKGEsYil7dGhpcy5hLksoMCxu
+ZXcgVy5LUyh0aGlzLHUuZUEuYShiKSkpfSwKZ1Y6ZnVuY3Rpb24oKXt2YXIgdD1ILlZNKFtdLHUucykK
+dGhpcy5hLksoMCxuZXcgVy5BMyh0aGlzLHQpKQpyZXR1cm4gdH0sCmdBOmZ1bmN0aW9uKGEpe3JldHVy
+biB0aGlzLmdWKCkubGVuZ3RofSwKazpmdW5jdGlvbihhKXt2YXIgdCxzLHI9SC5WTShhLnNwbGl0KCIt
+IiksdS5zKQpmb3IodD0xO3Q8ci5sZW5ndGg7Kyt0KXtzPXJbdF0KaWYocy5sZW5ndGg+MClDLk5tLlko
+cix0LHNbMF0udG9VcHBlckNhc2UoKStKLktWKHMsMSkpfXJldHVybiBDLk5tLnpWKHIsIiIpfSwKTzpm
+dW5jdGlvbihhKXt2YXIgdCxzLHIscSxwCmZvcih0PWEubGVuZ3RoLHM9MCxyPSIiO3M8dDsrK3Mpe3E9
+YVtzXQpwPXEudG9Mb3dlckNhc2UoKQpyPShxIT09cCYmcz4wP3IrIi0iOnIpK3B9cmV0dXJuIHIuY2hh
+ckNvZGVBdCgwKT09MD9yOnJ9fQpXLktTLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7aWYoSi5y
+WShhKS5uKGEsImRhdGEtIikpdGhpcy5iLiQyKHRoaXMuYS5rKEMueEIuRyhhLDUpKSxiKX0sCiRTOjd9
+ClcuQTMucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXtpZihKLnJZKGEpLm4oYSwiZGF0YS0iKSlD
+Lk5tLmkodGhpcy5iLHRoaXMuYS5rKEMueEIuRyhhLDUpKSl9LAokUzo3fQpXLkk0LnByb3RvdHlwZT17
+CkRHOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscD1QLkxzKHUuTikKZm9yKHQ9dGhpcy5hLmNsYXNzTmFt
+ZS5zcGxpdCgiICIpLHM9dC5sZW5ndGgscj0wO3I8czsrK3Ipe3E9Si5UMCh0W3JdKQppZihxLmxlbmd0
+aCE9PTApcC5pKDAscSl9cmV0dXJuIHB9LApwOmZ1bmN0aW9uKGEpe3RoaXMuYS5jbGFzc05hbWU9dS5D
+LmEoYSkuelYoMCwiICIpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5jbGFzc0xpc3QubGVu
+Z3RofSwKVjE6ZnVuY3Rpb24oYSl7dGhpcy5hLmNsYXNzTmFtZT0iIn0sCnRnOmZ1bmN0aW9uKGEsYil7
+dmFyIHQ9dGhpcy5hLmNsYXNzTGlzdC5jb250YWlucyhiKQpyZXR1cm4gdH0sCmk6ZnVuY3Rpb24oYSxi
+KXt2YXIgdD10aGlzLmEuY2xhc3NMaXN0LHM9dC5jb250YWlucyhiKQp0LmFkZChiKQpyZXR1cm4hc30s
+ClI6ZnVuY3Rpb24oYSxiKXt2YXIgdD10aGlzLmEuY2xhc3NMaXN0LHM9dC5jb250YWlucyhiKQp0LnJl
+bW92ZShiKQpyZXR1cm4gc30sCkZWOmZ1bmN0aW9uKGEsYil7Vy5UTih0aGlzLmEsdS5RLmEoYikpfX0K
+Vy5Gay5wcm90b3R5cGU9e30KVy5STy5wcm90b3R5cGU9e30KVy5ldS5wcm90b3R5cGU9e30KVy54Qy5w
+cm90b3R5cGU9e30KVy52Ti5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLiQx
+KHUuQi5hKGEpKX0sCiRTOjI4fQpXLkpRLnByb3RvdHlwZT17CkNZOmZ1bmN0aW9uKGEpe3ZhciB0Cmlm
+KCQub3IuYT09PTApe2Zvcih0PTA7dDwyNjI7Kyt0KSQub3IuWSgwLEMuY21bdF0sVy5wUygpKQpmb3Io
+dD0wO3Q8MTI7Kyt0KSQub3IuWSgwLEMuQklbdF0sVy5WNCgpKX19LAppMDpmdW5jdGlvbihhKXtyZXR1
+cm4gJC5BTigpLnRnKDAsVy5yUyhhKSl9LApFYjpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9JC5vci5xKDAs
+Vy5yUyhhKSsiOjoiK2IpCmlmKHQ9PW51bGwpdD0kLm9yLnEoMCwiKjo6IitiKQppZih0PT1udWxsKXJl
+dHVybiExCnJldHVybiBILnk4KHQuJDQoYSxiLGMsdGhpcykpfSwKJGlrRjoxfQpXLkdtLnByb3RvdHlw
+ZT17CmdrejpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFcuVzkoYSx0aGlzLmdBKGEpLEgueihhKS5DKCJX
+OTxHbS5FPiIpKX19ClcudkQucHJvdG90eXBlPXsKaTA6ZnVuY3Rpb24oYSl7cmV0dXJuIEMuTm0uVnIo
+dGhpcy5hLG5ldyBXLlV2KGEpKX0sCkViOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gQy5ObS5Wcih0aGlz
+LmEsbmV3IFcuRWcoYSxiLGMpKX0sCiRpa0Y6MX0KVy5Vdi5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihh
+KXtyZXR1cm4gdS5lLmEoYSkuaTAodGhpcy5hKX0sCiRTOjEzfQpXLkVnLnByb3RvdHlwZT17CiQxOmZ1
+bmN0aW9uKGEpe3JldHVybiB1LmUuYShhKS5FYih0aGlzLmEsdGhpcy5iLHRoaXMuYyl9LAokUzoxM30K
+Vy5tNi5wcm90b3R5cGU9ewpDWTpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxzLHIKdGhpcy5hLkZWKDAs
+YykKdD1iLmV2KDAsbmV3IFcuRW8oKSkKcz1iLmV2KDAsbmV3IFcuV2soKSkKdGhpcy5iLkZWKDAsdCkK
+cj10aGlzLmMKci5GVigwLEMueEQpCnIuRlYoMCxzKX0sCmkwOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlz
+LmEudGcoMCxXLnJTKGEpKX0sCkViOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD10aGlzLHM9Vy5yUyhhKSxy
+PXQuYwppZihyLnRnKDAscysiOjoiK2IpKXJldHVybiB0LmQuRHQoYykKZWxzZSBpZihyLnRnKDAsIio6
+OiIrYikpcmV0dXJuIHQuZC5EdChjKQplbHNle3I9dC5iCmlmKHIudGcoMCxzKyI6OiIrYikpcmV0dXJu
+ITAKZWxzZSBpZihyLnRnKDAsIio6OiIrYikpcmV0dXJuITAKZWxzZSBpZihyLnRnKDAscysiOjoqIikp
+cmV0dXJuITAKZWxzZSBpZihyLnRnKDAsIio6OioiKSlyZXR1cm4hMH1yZXR1cm4hMX0sCiRpa0Y6MX0K
+Vy5Fby5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4hQy5ObS50ZyhDLkJJLEguaChhKSl9
+LAokUzoxNH0KVy5Xay5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gQy5ObS50ZyhDLkJJ
+LEguaChhKSl9LAokUzoxNH0KVy5jdC5wcm90b3R5cGU9ewpFYjpmdW5jdGlvbihhLGIsYyl7aWYodGhp
+cy5qRihhLGIsYykpcmV0dXJuITAKaWYoYj09PSJ0ZW1wbGF0ZSImJmM9PT0iIilyZXR1cm4hMAppZihh
+LmdldEF0dHJpYnV0ZSgidGVtcGxhdGUiKT09PSIiKXJldHVybiB0aGlzLmUudGcoMCxiKQpyZXR1cm4h
+MX19ClcuSUEucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIlRFTVBMQVRFOjoiK0guRWoo
+SC5oKGEpKX0sCiRTOjZ9ClcuT3cucHJvdG90eXBlPXsKaTA6ZnVuY3Rpb24oYSl7dmFyIHQKaWYodS5l
+dy5iKGEpKXJldHVybiExCnQ9dS5nNy5iKGEpCmlmKHQmJlcuclMoYSk9PT0iZm9yZWlnbk9iamVjdCIp
+cmV0dXJuITEKaWYodClyZXR1cm4hMApyZXR1cm4hMX0sCkViOmZ1bmN0aW9uKGEsYixjKXtpZihiPT09
+ImlzInx8Qy54Qi5uKGIsIm9uIikpcmV0dXJuITEKcmV0dXJuIHRoaXMuaTAoYSl9LAokaWtGOjF9Clcu
+VzkucHJvdG90eXBlPXsKRjpmdW5jdGlvbigpe3ZhciB0PXRoaXMscz10LmMrMSxyPXQuYgppZihzPHIp
+e3Quc00oSi54OSh0LmEscykpCnQuYz1zCnJldHVybiEwfXQuc00obnVsbCkKdC5jPXIKcmV0dXJuITF9
+LApnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmR9LApzTTpmdW5jdGlvbihhKXt0aGlzLmQ9dGhpcy4k
+dGkuQygiMT8iKS5hKGEpfSwKJGlBbjoxfQpXLmRXLnByb3RvdHlwZT17CmdtVzpmdW5jdGlvbihhKXty
+ZXR1cm4gVy5ISCh0aGlzLmEubG9jYXRpb24pfSwKJGlEMDoxLAokaXY2OjF9ClcuRmIucHJvdG90eXBl
+PXt9Clcua0YucHJvdG90eXBlPXt9ClcubWsucHJvdG90eXBlPXskaXkwOjF9ClcuS28ucHJvdG90eXBl
+PXsKUG46ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcyxzPW5ldyBXLmZtKHQpCnQuYj0hMQpzLiQyKGEsbnVs
+bCkKZm9yKDt0LmI7KXt0LmI9ITEKcy4kMihhLG51bGwpfX0sCkVQOmZ1bmN0aW9uKGEsYil7dmFyIHQ9
+dGhpcy5iPSEwCmlmKGIhPW51bGw/YiE9PWEucGFyZW50Tm9kZTp0KUouTHQoYSkKZWxzZSBiLnJlbW92
+ZUNoaWxkKGEpfSwKSTQ6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG89ITAsbj1udWxsLG09bnVs
+bAp0cnl7bj1KLmlnKGEpCm09bi5hLmdldEF0dHJpYnV0ZSgiaXMiKQp1LmguYShhKQp0PWZ1bmN0aW9u
+KGMpe2lmKCEoYy5hdHRyaWJ1dGVzIGluc3RhbmNlb2YgTmFtZWROb2RlTWFwKSlyZXR1cm4gdHJ1ZQpp
+ZihjLmlkPT0nbGFzdENoaWxkJ3x8Yy5uYW1lPT0nbGFzdENoaWxkJ3x8Yy5pZD09J3ByZXZpb3VzU2li
+bGluZyd8fGMubmFtZT09J3ByZXZpb3VzU2libGluZyd8fGMuaWQ9PSdjaGlsZHJlbid8fGMubmFtZT09
+J2NoaWxkcmVuJylyZXR1cm4gdHJ1ZQp2YXIgbD1jLmNoaWxkTm9kZXMKaWYoYy5sYXN0Q2hpbGQmJmMu
+bGFzdENoaWxkIT09bFtsLmxlbmd0aC0xXSlyZXR1cm4gdHJ1ZQppZihjLmNoaWxkcmVuKWlmKCEoYy5j
+aGlsZHJlbiBpbnN0YW5jZW9mIEhUTUxDb2xsZWN0aW9ufHxjLmNoaWxkcmVuIGluc3RhbmNlb2YgTm9k
+ZUxpc3QpKXJldHVybiB0cnVlCnZhciBrPTAKaWYoYy5jaGlsZHJlbilrPWMuY2hpbGRyZW4ubGVuZ3Ro
+CmZvcih2YXIgaj0wO2o8aztqKyspe3ZhciBpPWMuY2hpbGRyZW5bal0KaWYoaS5pZD09J2F0dHJpYnV0
+ZXMnfHxpLm5hbWU9PSdhdHRyaWJ1dGVzJ3x8aS5pZD09J2xhc3RDaGlsZCd8fGkubmFtZT09J2xhc3RD
+aGlsZCd8fGkuaWQ9PSdwcmV2aW91c1NpYmxpbmcnfHxpLm5hbWU9PSdwcmV2aW91c1NpYmxpbmcnfHxp
+LmlkPT0nY2hpbGRyZW4nfHxpLm5hbWU9PSdjaGlsZHJlbicpcmV0dXJuIHRydWV9cmV0dXJuIGZhbHNl
+fShhKQpvPUgub1QodCk/ITA6IShhLmF0dHJpYnV0ZXMgaW5zdGFuY2VvZiBOYW1lZE5vZGVNYXApfWNh
+dGNoKHEpe0guUnUocSl9cz0iZWxlbWVudCB1bnByaW50YWJsZSIKdHJ5e3M9Si5qKGEpfWNhdGNoKHEp
+e0guUnUocSl9dHJ5e3I9Vy5yUyhhKQp0aGlzLmtSKHUuaC5hKGEpLGIsbyxzLHIsdS52LmEobiksSC5r
+KG0pKX1jYXRjaChxKXtpZihILlJ1KHEpIGluc3RhbmNlb2YgUC51KXRocm93IHEKZWxzZXt0aGlzLkVQ
+KGEsYikKd2luZG93CnA9IlJlbW92aW5nIGNvcnJ1cHRlZCBlbGVtZW50ICIrSC5FaihzKQppZih0eXBl
+b2YgY29uc29sZSE9InVuZGVmaW5lZCIpd2luZG93LmNvbnNvbGUud2FybihwKX19fSwKa1I6ZnVuY3Rp
+b24oYSxiLGMsZCxlLGYsZyl7dmFyIHQscyxyLHEscCxvLG49dGhpcwppZihjKXtuLkVQKGEsYikKd2lu
+ZG93CnQ9IlJlbW92aW5nIGVsZW1lbnQgZHVlIHRvIGNvcnJ1cHRlZCBhdHRyaWJ1dGVzIG9uIDwiK2Qr
+Ij4iCmlmKHR5cGVvZiBjb25zb2xlIT0idW5kZWZpbmVkIil3aW5kb3cuY29uc29sZS53YXJuKHQpCnJl
+dHVybn1pZighbi5hLmkwKGEpKXtuLkVQKGEsYikKd2luZG93CnQ9IlJlbW92aW5nIGRpc2FsbG93ZWQg
+ZWxlbWVudCA8IitlKyI+IGZyb20gIitILkVqKGIpCmlmKHR5cGVvZiBjb25zb2xlIT0idW5kZWZpbmVk
+Iil3aW5kb3cuY29uc29sZS53YXJuKHQpCnJldHVybn1pZihnIT1udWxsKWlmKCFuLmEuRWIoYSwiaXMi
+LGcpKXtuLkVQKGEsYikKd2luZG93CnQ9IlJlbW92aW5nIGRpc2FsbG93ZWQgdHlwZSBleHRlbnNpb24g
+PCIrZSsnIGlzPSInK2crJyI+JwppZih0eXBlb2YgY29uc29sZSE9InVuZGVmaW5lZCIpd2luZG93LmNv
+bnNvbGUud2Fybih0KQpyZXR1cm59dD1mLmdWKCkKcz1ILlZNKHQuc2xpY2UoMCksSC50Nih0KS5DKCJq
+ZDwxPiIpKQpmb3Iocj1mLmdWKCkubGVuZ3RoLTEsdD1mLmE7cj49MDstLXIpe2lmKHI+PXMubGVuZ3Ro
+KXJldHVybiBILk9IKHMscikKcT1zW3JdCnA9bi5hCm89Si5jSChxKQpILmgocSkKaWYoIXAuRWIoYSxv
+LHQuZ2V0QXR0cmlidXRlKHEpKSl7d2luZG93CnA9IlJlbW92aW5nIGRpc2FsbG93ZWQgYXR0cmlidXRl
+IDwiK2UrIiAiK3ErJz0iJytILkVqKHQuZ2V0QXR0cmlidXRlKHEpKSsnIj4nCmlmKHR5cGVvZiBjb25z
b2xlIT0idW5kZWZpbmVkIil3aW5kb3cuY29uc29sZS53YXJuKHApCnQucmVtb3ZlQXR0cmlidXRlKHEp
fX1pZih1LmFXLmIoYSkpbi5QbihhLmNvbnRlbnQpfSwKJGlvbjoxfQpXLmZtLnByb3RvdHlwZT17CiQy
OmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvLG49dGhpcy5hCnN3aXRjaChhLm5vZGVUeXBlKXtj
@@ -3210,949 +3227,957 @@
YXVsdDpuLkVQKGEsYil9dD1hLmxhc3RDaGlsZApmb3Iocj11LkE7bnVsbCE9dDspe3M9bnVsbAp0cnl7
cz10LnByZXZpb3VzU2libGluZwppZihzIT1udWxsKXtxPXMubmV4dFNpYmxpbmcKcD10CnA9cT09bnVs
bD9wIT1udWxsOnEhPT1wCnE9cH1lbHNlIHE9ITEKaWYocSl7cT1QLlBWKCJDb3JydXB0IEhUTUwiKQp0
-aHJvdyBILmIocSl9fWNhdGNoKG8pe0guUnUobykKcT1yLmEodCkKbi5iPSEwCnA9cS5wYXJlbnROb2Rl
-CnA9YT09bnVsbD9wIT1udWxsOmEhPT1wCmlmKHApe3A9cS5wYXJlbnROb2RlCmlmKHAhPW51bGwpcC5y
-ZW1vdmVDaGlsZChxKX1lbHNlIGEucmVtb3ZlQ2hpbGQocSkKdD1udWxsCnM9YS5sYXN0Q2hpbGR9aWYo
-dCE9bnVsbCl0aGlzLiQyKHQsYSkKdD1zfX0sCiRTOjMxfQpXLkxlLnByb3RvdHlwZT17fQpXLks3LnBy
-b3RvdHlwZT17fQpXLnJCLnByb3RvdHlwZT17fQpXLlhXLnByb3RvdHlwZT17fQpXLm9hLnByb3RvdHlw
-ZT17fQpQLmlKLnByb3RvdHlwZT17ClZIOmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcy5hLHI9cy5sZW5n
-dGgKZm9yKHQ9MDt0PHI7Kyt0KWlmKHNbdF09PT1hKXJldHVybiB0CkMuTm0uaShzLGEpCkMuTm0uaSh0
-aGlzLmIsbnVsbCkKcmV0dXJuIHJ9LApQdjpmdW5jdGlvbihhKXt2YXIgdCxzLHIscT10aGlzLHA9e30K
-aWYoYT09bnVsbClyZXR1cm4gYQppZihILnJRKGEpKXJldHVybiBhCmlmKHR5cGVvZiBhPT0ibnVtYmVy
-IilyZXR1cm4gYQppZih0eXBlb2YgYT09InN0cmluZyIpcmV0dXJuIGEKaWYoYSBpbnN0YW5jZW9mIFAu
-aVApcmV0dXJuIG5ldyBEYXRlKGEuYSkKaWYodS5mdi5iKGEpKXRocm93IEguYihQLm4oInN0cnVjdHVy
-ZWQgY2xvbmUgb2YgUmVnRXhwIikpCmlmKHUuYzguYihhKSlyZXR1cm4gYQppZih1LmQuYihhKSlyZXR1
-cm4gYQppZih1LkkuYihhKSlyZXR1cm4gYQp0PXUuZEQuYihhKXx8ITEKaWYodClyZXR1cm4gYQppZih1
-LkcuYihhKSl7cz1xLlZIKGEpCnQ9cS5iCmlmKHM+PXQubGVuZ3RoKXJldHVybiBILmsodCxzKQpyPXAu
-YT10W3NdCmlmKHIhPW51bGwpcmV0dXJuIHIKcj17fQpwLmE9cgpDLk5tLlkodCxzLHIpCmEuSygwLG5l
-dyBQLmpnKHAscSkpCnJldHVybiBwLmF9aWYodS5qLmIoYSkpe3M9cS5WSChhKQpwPXEuYgppZihzPj1w
-Lmxlbmd0aClyZXR1cm4gSC5rKHAscykKcj1wW3NdCmlmKHIhPW51bGwpcmV0dXJuIHIKcmV0dXJuIHEu
-ZWsoYSxzKX1pZih1LmVILmIoYSkpe3M9cS5WSChhKQp0PXEuYgppZihzPj10Lmxlbmd0aClyZXR1cm4g
-SC5rKHQscykKcj1wLmI9dFtzXQppZihyIT1udWxsKXJldHVybiByCnI9e30KcC5iPXIKQy5ObS5ZKHQs
-cyxyKQpxLmltKGEsbmV3IFAuVGEocCxxKSkKcmV0dXJuIHAuYn10aHJvdyBILmIoUC5uKCJzdHJ1Y3R1
-cmVkIGNsb25lIG9mIG90aGVyIHR5cGUiKSl9LAplazpmdW5jdGlvbihhLGIpe3ZhciB0LHM9Si5VNihh
-KSxyPXMuZ0EoYSkscT1uZXcgQXJyYXkocikKQy5ObS5ZKHRoaXMuYixiLHEpCmZvcih0PTA7dDxyOysr
-dClDLk5tLlkocSx0LHRoaXMuUHYocy5xKGEsdCkpKQpyZXR1cm4gcX19ClAuamcucHJvdG90eXBlPXsK
-JDI6ZnVuY3Rpb24oYSxiKXt0aGlzLmEuYVthXT10aGlzLmIuUHYoYil9LAokUzoyfQpQLlRhLnByb3Rv
-dHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dGhpcy5hLmJbYV09dGhpcy5iLlB2KGIpfSwKJFM6Mn0KUC5C
-Zi5wcm90b3R5cGU9ewppbTpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxCnUuYjguYShiKQpmb3IodD1P
-YmplY3Qua2V5cyhhKSxzPXQubGVuZ3RoLHI9MDtyPHM7KytyKXtxPXRbcl0KYi4kMihxLGFbcV0pfX19
-ClAuQXMucHJvdG90eXBlPXsKVDpmdW5jdGlvbihhKXt2YXIgdApILmMoYSkKdD0kLmhHKCkuYgppZih0
-eXBlb2YgYSE9InN0cmluZyIpSC52aChILkkoYSkpCmlmKHQudGVzdChhKSlyZXR1cm4gYQp0aHJvdyBI
-LmIoUC5MMyhhLCJ2YWx1ZSIsIk5vdCBhIHZhbGlkIGNsYXNzIHRva2VuIikpfSwKWjpmdW5jdGlvbihh
-KXtyZXR1cm4gdGhpcy53KCkuelYoMCwiICIpfSwKZ2t6OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMudygp
-CnJldHVybiBQLnJqKHQsdC5yLEguTGgodCkuYyl9LApnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy53
-KCkuYX0sCnRnOmZ1bmN0aW9uKGEsYil7dGhpcy5UKGIpCnJldHVybiB0aGlzLncoKS50ZygwLGIpfSwK
-aTpmdW5jdGlvbihhLGIpe3RoaXMuVChiKQpyZXR1cm4gSC5FOSh0aGlzLk9TKG5ldyBQLkdFKGIpKSl9
-LApSOmZ1bmN0aW9uKGEsYil7dmFyIHQscwp0aGlzLlQoYikKdD10aGlzLncoKQpzPXQuUigwLGIpCnRo
-aXMucCh0KQpyZXR1cm4gc30sCkZWOmZ1bmN0aW9uKGEsYil7dGhpcy5PUyhuZXcgUC5ONyh0aGlzLHUu
-WC5hKGIpKSl9LApWMTpmdW5jdGlvbihhKXt0aGlzLk9TKG5ldyBQLnVRKCkpfSwKT1M6ZnVuY3Rpb24o
-YSl7dmFyIHQscwp1LmJVLmEoYSkKdD10aGlzLncoKQpzPWEuJDEodCkKdGhpcy5wKHQpCnJldHVybiBz
-fX0KUC5HRS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdS5DLmEoYSkuaSgwLHRoaXMu
-YSl9LAokUzo1MH0KUC5ONy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmIscz1I
-LnQ2KHQpCnJldHVybiB1LkMuYShhKS5GVigwLG5ldyBILmxKKHQscy5DKCJxVSgxKSIpLmEodGhpcy5h
-Lmd1TSgpKSxzLkMoImxKPDEscVU+IikpKX0sCiRTOjE2fQpQLnVRLnByb3RvdHlwZT17CiQxOmZ1bmN0
-aW9uKGEpe3UuQy5hKGEpCmlmKGEuYT4wKXthLmI9YS5jPWEuZD1hLmU9YS5mPW51bGwKYS5hPTAKYS5Y
-KCl9cmV0dXJuIG51bGx9LAokUzoxNn0KUC5oRi5wcm90b3R5cGU9eyRpaEY6MX0KUC5QQy5wcm90b3R5
-cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdAp1LlouYShhKQp0PWZ1bmN0aW9uKGIsYyxkKXtyZXR1cm4g
-ZnVuY3Rpb24oKXtyZXR1cm4gYihjLGQsdGhpcyxBcnJheS5wcm90b3R5cGUuc2xpY2UuYXBwbHkoYXJn
-dW1lbnRzKSl9fShQLlI0LGEsITEpClAuRG0odCwkLndRKCksYSkKcmV0dXJuIHR9LAokUzo2fQpQLm10
-LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgdGhpcy5hKGEpfSwKJFM6Nn0KUC5O
-ei5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAucjcoYSl9LAokUzozNX0KUC5R
-Uy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuVHooYSx1LmFtKX0sCiRTOjM2
-fQpQLm5wLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5FNChhKX0sCiRTOjM3
-fQpQLkU0LnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtpZih0eXBlb2YgYiE9InN0cmluZyImJnR5
-cGVvZiBiIT0ibnVtYmVyIil0aHJvdyBILmIoUC54WSgicHJvcGVydHkgaXMgbm90IGEgU3RyaW5nIG9y
-IG51bSIpKQpyZXR1cm4gUC5MNyh0aGlzLmFbYl0pfSwKWTpmdW5jdGlvbihhLGIsYyl7aWYodHlwZW9m
-IGIhPSJzdHJpbmciJiZ0eXBlb2YgYiE9Im51bWJlciIpdGhyb3cgSC5iKFAueFkoInByb3BlcnR5IGlz
-IG5vdCBhIFN0cmluZyBvciBudW0iKSkKdGhpcy5hW2JdPVAud1koYyl9LApETjpmdW5jdGlvbihhLGIp
-e2lmKGI9PW51bGwpcmV0dXJuITEKcmV0dXJuIGIgaW5zdGFuY2VvZiBQLkU0JiZ0aGlzLmE9PT1iLmF9
-LApaOmZ1bmN0aW9uKGEpe3ZhciB0LHMKdHJ5e3Q9U3RyaW5nKHRoaXMuYSkKcmV0dXJuIHR9Y2F0Y2go
-cyl7SC5SdShzKQp0PXRoaXMueGIoMCkKcmV0dXJuIHR9fSwKVjc6ZnVuY3Rpb24oYSxiKXt2YXIgdCxz
-PXRoaXMuYQppZihiPT1udWxsKXQ9bnVsbAplbHNle3Q9SC50NihiKQp0PVAuQ0gobmV3IEgubEooYix0
-LkMoIkAoMSkiKS5hKFAuaUcoKSksdC5DKCJsSjwxLEA+IikpLCEwLHUueil9cmV0dXJuIFAuTDcoc1th
-XS5hcHBseShzLHQpKX0sCmdpTzpmdW5jdGlvbihhKXtyZXR1cm4gMH19ClAucjcucHJvdG90eXBlPXt9
-ClAuVHoucHJvdG90eXBlPXsKY1A6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcyxzPWE8MHx8YT49dC5nQSh0
-KQppZihzKXRocm93IEguYihQLlRFKGEsMCx0LmdBKHQpLG51bGwsbnVsbCkpfSwKcTpmdW5jdGlvbihh
-LGIpe2lmKEgub2soYikpdGhpcy5jUChiKQpyZXR1cm4gdGhpcy4kdGkuYy5hKHRoaXMuVXIoMCxiKSl9
-LApZOmZ1bmN0aW9uKGEsYixjKXt0aGlzLmNQKGIpCnRoaXMuZTQoMCxiLGMpfSwKZ0E6ZnVuY3Rpb24o
-YSl7dmFyIHQ9dGhpcy5hLmxlbmd0aAppZih0eXBlb2YgdD09PSJudW1iZXIiJiZ0Pj4+MD09PXQpcmV0
-dXJuIHQKdGhyb3cgSC5iKFAuUFYoIkJhZCBKc0FycmF5IGxlbmd0aCIpKX0sCiRpYlE6MSwKJGljWDox
-LAokaXpNOjF9ClAuY28ucHJvdG90eXBlPXt9ClAuYkIucHJvdG90eXBlPXskaWJCOjF9ClAuS2UucHJv
-dG90eXBlPXsKdzpmdW5jdGlvbigpe3ZhciB0LHMscixxLHA9dGhpcy5hLmdldEF0dHJpYnV0ZSgiY2xh
-c3MiKSxvPVAuTHModS5OKQppZihwPT1udWxsKXJldHVybiBvCmZvcih0PXAuc3BsaXQoIiAiKSxzPXQu
-bGVuZ3RoLHI9MDtyPHM7KytyKXtxPUouVDAodFtyXSkKaWYocS5sZW5ndGghPT0wKW8uaSgwLHEpfXJl
-dHVybiBvfSwKcDpmdW5jdGlvbihhKXt0aGlzLmEuc2V0QXR0cmlidXRlKCJjbGFzcyIsYS56VigwLCIg
-IikpfX0KUC5kNS5wcm90b3R5cGU9ewpnUDpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuS2UoYSl9LApz
-aGY6ZnVuY3Rpb24oYSxiKXt0aGlzLllDKGEsYil9LApyNjpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxz
-LHIscSxwLG8KaWYoZD09bnVsbCl7dD1ILlZNKFtdLHUuaykKZD1uZXcgVy52RCh0KQpDLk5tLmkodCxX
-LlR3KG51bGwpKQpDLk5tLmkodCxXLkJsKCkpCkMuTm0uaSh0LG5ldyBXLk93KCkpfWM9bmV3IFcuS28o
-ZCkKcz0nPHN2ZyB2ZXJzaW9uPSIxLjEiPicrSC5kKGIpKyI8L3N2Zz4iCnQ9ZG9jdW1lbnQKcj10LmJv
-ZHkKci50b1N0cmluZwpxPUMuUlkuQUgocixzLGMpCnA9dC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCkK
-cS50b1N0cmluZwp0PW5ldyBXLmU3KHEpCm89dC5ncjgodCkKZm9yKDt0PW8uZmlyc3RDaGlsZCx0IT1u
-dWxsOylwLmFwcGVuZENoaWxkKHQpCnJldHVybiBwfSwKbno6ZnVuY3Rpb24oYSxiLGMsZCxlKXt0aHJv
-dyBILmIoUC5MNCgiQ2Fubm90IGludm9rZSBpbnNlcnRBZGphY2VudEh0bWwgb24gU1ZHLiIpKX0sCmdW
-bDpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFcuZXUoYSwiY2xpY2siLCExLHUuUSl9LAokaWQ1OjF9ClAu
-bjYucHJvdG90eXBlPXskaWJROjEsJGljWDoxLCRpek06MSwkaUFTOjF9ClUuZDIucHJvdG90eXBlPXt9
-ClUuU2UucHJvdG90eXBlPXt9ClUuTWwucHJvdG90eXBlPXt9ClUueUQucHJvdG90eXBlPXt9ClUud2Iu
-cHJvdG90eXBlPXt9CkIuajgucHJvdG90eXBlPXt9CkIucXAucHJvdG90eXBlPXt9ClQubVEucHJvdG90
-eXBlPXt9CkwuZS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbgp1LkIu
-YShhKQp0PXdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZQpzPUwuRzYod2luZG93LmxvY2F0aW9uLmhyZWYp
-CnI9TC5hSyh3aW5kb3cubG9jYXRpb24uaHJlZikKTC5HZSgpCmlmKHQhPT0iLyImJnQhPT1KLlQwKGRv
-Y3VtZW50LnF1ZXJ5U2VsZWN0b3IoIi5yb290IikudGV4dENvbnRlbnQpKUwuRzcodCxzLHIsITAsbmV3
-IEwuVlcodCxzLHIpKQpxPWRvY3VtZW50CnA9Si5xRihxLnF1ZXJ5U2VsZWN0b3IoIi5hcHBseS1taWdy
-YXRpb24iKSkKbz1wLiR0aQpuPW8uQygifigxKSIpLmEobmV3IEwub1ooKSkKdS5NLmEobnVsbCkKVy5K
+aHJvdyBILmIocSl9fWNhdGNoKG8pe0guUnUobykKcT1yLmEodCkKbi5iPSEwCmlmKGEhPT1xLnBhcmVu
+dE5vZGUpe3A9cS5wYXJlbnROb2RlCmlmKHAhPW51bGwpcC5yZW1vdmVDaGlsZChxKX1lbHNlIGEucmVt
+b3ZlQ2hpbGQocSkKdD1udWxsCnM9YS5sYXN0Q2hpbGR9aWYodCE9bnVsbCl0aGlzLiQyKHQsYSkKdD1z
+fX0sCiRTOjMxfQpXLkxlLnByb3RvdHlwZT17fQpXLks3LnByb3RvdHlwZT17fQpXLnJCLnByb3RvdHlw
+ZT17fQpXLlhXLnByb3RvdHlwZT17fQpXLm9hLnByb3RvdHlwZT17fQpQLmlKLnByb3RvdHlwZT17ClZI
+OmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcy5hLHI9cy5sZW5ndGgKZm9yKHQ9MDt0PHI7Kyt0KWlmKHNb
+dF09PT1hKXJldHVybiB0CkMuTm0uaShzLGEpCkMuTm0uaSh0aGlzLmIsbnVsbCkKcmV0dXJuIHJ9LApQ
+djpmdW5jdGlvbihhKXt2YXIgdCxzLHIscT10aGlzLHA9e30KaWYoYT09bnVsbClyZXR1cm4gYQppZihI
+LmwoYSkpcmV0dXJuIGEKaWYodHlwZW9mIGE9PSJudW1iZXIiKXJldHVybiBhCmlmKHR5cGVvZiBhPT0i
+c3RyaW5nIilyZXR1cm4gYQppZihhIGluc3RhbmNlb2YgUC5pUClyZXR1cm4gbmV3IERhdGUoYS5hKQpp
+Zih1LmZ2LmIoYSkpdGhyb3cgSC5iKFAuU1koInN0cnVjdHVyZWQgY2xvbmUgb2YgUmVnRXhwIikpCmlm
+KHUuYzguYihhKSlyZXR1cm4gYQppZih1LncuYihhKSlyZXR1cm4gYQppZih1LkkuYihhKSlyZXR1cm4g
+YQp0PXUuZEUuYihhKXx8ITEKaWYodClyZXR1cm4gYQppZih1LnYuYihhKSl7cz1xLlZIKGEpCnQ9cS5i
+CmlmKHM+PXQubGVuZ3RoKXJldHVybiBILk9IKHQscykKcj1wLmE9dFtzXQppZihyIT1udWxsKXJldHVy
+biByCnI9e30KcC5hPXIKQy5ObS5ZKHQscyxyKQphLksoMCxuZXcgUC5qZyhwLHEpKQpyZXR1cm4gcC5h
+fWlmKHUuai5iKGEpKXtzPXEuVkgoYSkKcD1xLmIKaWYocz49cC5sZW5ndGgpcmV0dXJuIEguT0gocCxz
+KQpyPXBbc10KaWYociE9bnVsbClyZXR1cm4gcgpyZXR1cm4gcS5layhhLHMpfWlmKHUuZUguYihhKSl7
+cz1xLlZIKGEpCnQ9cS5iCmlmKHM+PXQubGVuZ3RoKXJldHVybiBILk9IKHQscykKcj1wLmI9dFtzXQpp
+ZihyIT1udWxsKXJldHVybiByCnI9e30KcC5iPXIKQy5ObS5ZKHQscyxyKQpxLmltKGEsbmV3IFAuVGEo
+cCxxKSkKcmV0dXJuIHAuYn10aHJvdyBILmIoUC5TWSgic3RydWN0dXJlZCBjbG9uZSBvZiBvdGhlciB0
+eXBlIikpfSwKZWs6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzPUouVTYoYSkscj1zLmdBKGEpLHE9bmV3IEFy
+cmF5KHIpCkMuTm0uWSh0aGlzLmIsYixxKQpmb3IodD0wO3Q8cjsrK3QpQy5ObS5ZKHEsdCx0aGlzLlB2
+KHMucShhLHQpKSkKcmV0dXJuIHF9fQpQLmpnLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dGhp
+cy5hLmFbYV09dGhpcy5iLlB2KGIpfSwKJFM6Mn0KUC5UYS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihh
+LGIpe3RoaXMuYS5iW2FdPXRoaXMuYi5QdihiKX0sCiRTOjJ9ClAuQmYucHJvdG90eXBlPXsKaW06ZnVu
+Y3Rpb24oYSxiKXt2YXIgdCxzLHIscQp1LmI4LmEoYikKZm9yKHQ9T2JqZWN0LmtleXMoYSkscz10Lmxl
+bmd0aCxyPTA7cjxzOysrcil7cT10W3JdCmIuJDIocSxhW3FdKX19fQpQLkFzLnByb3RvdHlwZT17ClQ6
+ZnVuY3Rpb24oYSl7dmFyIHQKSC5oKGEpCnQ9JC5oRygpLmIKaWYodHlwZW9mIGEhPSJzdHJpbmciKUgu
+dmgoSC50TChhKSkKaWYodC50ZXN0KGEpKXJldHVybiBhCnRocm93IEguYihQLkwzKGEsInZhbHVlIiwi
+Tm90IGEgdmFsaWQgY2xhc3MgdG9rZW4iKSl9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLkRHKCku
+elYoMCwiICIpfSwKZ2t6OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuREcoKQpyZXR1cm4gUC5yaih0LHQu
+cixILkxoKHQpLmMpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuREcoKS5hfSwKdGc6ZnVuY3Rp
+b24oYSxiKXt0aGlzLlQoYikKcmV0dXJuIHRoaXMuREcoKS50ZygwLGIpfSwKaTpmdW5jdGlvbihhLGIp
+e3ZhciB0CnRoaXMuVChiKQp0PXRoaXMuT1MobmV3IFAuR0UoYikpCnJldHVybiBILnk4KHQ9PW51bGw/
+ITE6dCl9LApSOmZ1bmN0aW9uKGEsYil7dmFyIHQscwp0aGlzLlQoYikKdD10aGlzLkRHKCkKcz10LlIo
+MCxiKQp0aGlzLnAodCkKcmV0dXJuIHN9LApGVjpmdW5jdGlvbihhLGIpe3RoaXMuT1MobmV3IFAuTjco
+dGhpcyx1LlEuYShiKSkpfSwKVjE6ZnVuY3Rpb24oYSl7dGhpcy5PUyhuZXcgUC51USgpKX0sCk9TOmZ1
+bmN0aW9uKGEpe3ZhciB0LHMKdS5iVS5hKGEpCnQ9dGhpcy5ERygpCnM9YS4kMSh0KQp0aGlzLnAodCkK
+cmV0dXJuIHN9fQpQLkdFLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB1LkMuYShhKS5p
+KDAsdGhpcy5hKX0sCiRTOjMzfQpQLk43LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0PXRo
+aXMuYixzPUgudDYodCkKcmV0dXJuIHUuQy5hKGEpLkZWKDAsbmV3IEgubEoodCxzLkMoInFVKDEpIiku
+YSh0aGlzLmEuZ3VNKCkpLHMuQygibEo8MSxxVT4iKSkpfSwKJFM6MTV9ClAudVEucHJvdG90eXBlPXsK
+JDE6ZnVuY3Rpb24oYSl7dS5DLmEoYSkKaWYoYS5hPjApe2EuYj1hLmM9YS5kPWEuZT1hLmY9bnVsbAph
+LmE9MAphLlgoKX1yZXR1cm4gbnVsbH0sCiRTOjE1fQpQLmhGLnByb3RvdHlwZT17JGloRjoxfQpQLlBD
+LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0CnUuWS5hKGEpCnQ9ZnVuY3Rpb24oYixjLGQp
+e3JldHVybiBmdW5jdGlvbigpe3JldHVybiBiKGMsZCx0aGlzLEFycmF5LnByb3RvdHlwZS5zbGljZS5h
+cHBseShhcmd1bWVudHMpKX19KFAuUjQsYSwhMSkKUC5EbSh0LCQudygpLGEpCnJldHVybiB0fSwKJFM6
+NX0KUC5tdC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IHRoaXMuYShhKX0sCiRT
+OjV9ClAuTnoucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLnI3KGEpfSwKJFM6
+NTN9ClAuUVMucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLlR6KGEsdS5hbSl9
+LAokUzozNn0KUC5ucC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuRTQoYSl9
+LAokUzozN30KUC5FNC5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7aWYodHlwZW9mIGIhPSJzdHJp
+bmciJiZ0eXBlb2YgYiE9Im51bWJlciIpdGhyb3cgSC5iKFAueFkoInByb3BlcnR5IGlzIG5vdCBhIFN0
+cmluZyBvciBudW0iKSkKcmV0dXJuIFAuTDcodGhpcy5hW2JdKX0sClk6ZnVuY3Rpb24oYSxiLGMpe2lm
+KHR5cGVvZiBiIT0ic3RyaW5nIiYmdHlwZW9mIGIhPSJudW1iZXIiKXRocm93IEguYihQLnhZKCJwcm9w
+ZXJ0eSBpcyBub3QgYSBTdHJpbmcgb3IgbnVtIikpCnRoaXMuYVtiXT1QLndZKGMpfSwKRE46ZnVuY3Rp
+b24oYSxiKXtpZihiPT1udWxsKXJldHVybiExCnJldHVybiBiIGluc3RhbmNlb2YgUC5FNCYmdGhpcy5h
+PT09Yi5hfSwKdzpmdW5jdGlvbihhKXt2YXIgdCxzCnRyeXt0PVN0cmluZyh0aGlzLmEpCnJldHVybiB0
+fWNhdGNoKHMpe0guUnUocykKdD10aGlzLnhiKDApCnJldHVybiB0fX0sClY3OmZ1bmN0aW9uKGEsYil7
+dmFyIHQscz10aGlzLmEKaWYoYj09bnVsbCl0PW51bGwKZWxzZXt0PUgudDYoYikKdD1QLkNIKG5ldyBI
+LmxKKGIsdC5DKCJAKDEpIikuYShQLmlHKCkpLHQuQygibEo8MSxAPiIpKSwhMCx1LnopfXJldHVybiBQ
+Lkw3KHNbYV0uYXBwbHkocyx0KSl9LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJuIDB9fQpQLnI3LnByb3Rv
+dHlwZT17fQpQLlR6LnByb3RvdHlwZT17CmNQOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMscz1hPDB8fGE+
+PXQuZ0EodCkKaWYocyl0aHJvdyBILmIoUC5URShhLDAsdC5nQSh0KSxudWxsLG51bGwpKX0sCnE6ZnVu
+Y3Rpb24oYSxiKXtpZihILm9rKGIpKXRoaXMuY1AoYikKcmV0dXJuIHRoaXMuJHRpLmMuYSh0aGlzLlVy
+KDAsYikpfSwKWTpmdW5jdGlvbihhLGIsYyl7dGhpcy5jUChiKQp0aGlzLmU0KDAsYixjKX0sCmdBOmZ1
+bmN0aW9uKGEpe3ZhciB0PXRoaXMuYS5sZW5ndGgKaWYodHlwZW9mIHQ9PT0ibnVtYmVyIiYmdD4+PjA9
+PT10KXJldHVybiB0CnRocm93IEguYihQLlBWKCJCYWQgSnNBcnJheSBsZW5ndGgiKSl9LAokaWJROjEs
+CiRpY1g6MSwKJGl6TToxfQpQLmNvLnByb3RvdHlwZT17fQpQLmJCLnByb3RvdHlwZT17JGliQjoxfQpQ
+LktlLnByb3RvdHlwZT17CkRHOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscD10aGlzLmEuZ2V0QXR0cmli
+dXRlKCJjbGFzcyIpLG89UC5Mcyh1Lk4pCmlmKHA9PW51bGwpcmV0dXJuIG8KZm9yKHQ9cC5zcGxpdCgi
+ICIpLHM9dC5sZW5ndGgscj0wO3I8czsrK3Ipe3E9Si5UMCh0W3JdKQppZihxLmxlbmd0aCE9PTApby5p
+KDAscSl9cmV0dXJuIG99LApwOmZ1bmN0aW9uKGEpe3RoaXMuYS5zZXRBdHRyaWJ1dGUoImNsYXNzIixh
+LnpWKDAsIiAiKSl9fQpQLmQ1LnByb3RvdHlwZT17CmdQOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5L
+ZShhKX0sCnNoZjpmdW5jdGlvbihhLGIpe3RoaXMuWUMoYSxiKX0sCnI2OmZ1bmN0aW9uKGEsYixjLGQp
+e3ZhciB0LHMscixxLHAsbwppZihkPT1udWxsKXt0PUguVk0oW10sdS5wKQpkPW5ldyBXLnZEKHQpCkMu
+Tm0uaSh0LFcuVHcobnVsbCkpCkMuTm0uaSh0LFcuQmwoKSkKQy5ObS5pKHQsbmV3IFcuT3coKSl9Yz1u
+ZXcgVy5LbyhkKQpzPSc8c3ZnIHZlcnNpb249IjEuMSI+JytILkVqKGIpKyI8L3N2Zz4iCnQ9ZG9jdW1l
+bnQKcj10LmJvZHkKci50b1N0cmluZwpxPUMuUlkuQUgocixzLGMpCnA9dC5jcmVhdGVEb2N1bWVudEZy
+YWdtZW50KCkKdD1uZXcgVy5lNyhxKQpvPXQuZ3I4KHQpCmZvcig7dD1vLmZpcnN0Q2hpbGQsdCE9bnVs
+bDspcC5hcHBlbmRDaGlsZCh0KQpyZXR1cm4gcH0sCm56OmZ1bmN0aW9uKGEsYixjLGQsZSl7dGhyb3cg
+SC5iKFAuTDQoIkNhbm5vdCBpbnZva2UgaW5zZXJ0QWRqYWNlbnRIdG1sIG9uIFNWRy4iKSl9LApnVmw6
+ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBXLmV1KGEsImNsaWNrIiwhMSx1LkcpfSwKJGlkNToxfQpQLm42
+LnByb3RvdHlwZT17JGliUToxLCRpY1g6MSwkaXpNOjEsJGlBUzoxfQpVLmQyLnByb3RvdHlwZT17fQpV
+LlNlLnByb3RvdHlwZT17fQpVLk1sLnByb3RvdHlwZT17fQpVLnlELnByb3RvdHlwZT17fQpVLndiLnBy
+b3RvdHlwZT17fQpCLmo4LnByb3RvdHlwZT17fQpCLnFwLnByb3RvdHlwZT17fQpULm1RLnByb3RvdHlw
+ZT17fQpMLmUucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG4KdS5hTC5h
+KGEpCnQ9d2luZG93LmxvY2F0aW9uLnBhdGhuYW1lCnM9TC5HNih3aW5kb3cubG9jYXRpb24uaHJlZikK
+cj1MLmFLKHdpbmRvdy5sb2NhdGlvbi5ocmVmKQpMLkdlKCkKaWYodCE9PSIvIiYmdCE9PUouVDAoZG9j
+dW1lbnQucXVlcnlTZWxlY3RvcigiLnJvb3QiKS50ZXh0Q29udGVudCkpTC5HNyh0LHMsciwhMCxuZXcg
+TC5WVyh0LHMscikpCnE9ZG9jdW1lbnQKcD1KLnFGKHEucXVlcnlTZWxlY3RvcigiLmFwcGx5LW1pZ3Jh
+dGlvbiIpKQpvPXAuJHRpCm49by5DKCJ+KDEpPyIpLmEobmV3IEwub1ooKSkKdS5aLmEobnVsbCkKVy5K
RShwLmEscC5iLG4sITEsby5jKQpvPUoucUYocS5xdWVyeVNlbGVjdG9yKCIucmVydW4tbWlncmF0aW9u
-IikpCm49by4kdGkKVy5KRShvLmEsby5iLG4uQygifigxKSIpLmEobmV3IEwueTgoKSksITEsbi5jKQpu
-PUoucUYocS5xdWVyeVNlbGVjdG9yKCIucmVwb3J0LXByb2JsZW0iKSkKbz1uLiR0aQpXLkpFKG4uYSxu
-LmIsby5DKCJ+KDEpIikuYShuZXcgTC5IaSgpKSwhMSxvLmMpCnE9Si5xRihxLnF1ZXJ5U2VsZWN0b3Io
-Ii5wb3B1cC1wYW5lIC5jbG9zZSIpKQpvPXEuJHRpClcuSkUocS5hLHEuYixvLkMoIn4oMSkiKS5hKG5l
-dyBMLkJUKCkpLCExLG8uYyl9LAokUzoxN30KTC5WVy5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe0wu
-RnIodGhpcy5hLHRoaXMuYix0aGlzLmMpfSwKJFM6MH0KTC5vWi5wcm90b3R5cGU9ewokMTpmdW5jdGlv
-bihhKXt1LlYuYShhKQppZihILm9UKHdpbmRvdy5jb25maXJtKCJUaGlzIHdpbGwgYXBwbHkgdGhlIGNo
-YW5nZXMgeW91J3ZlIHByZXZpZXdlZCB0byB5b3VyIHdvcmtpbmcgZGlyZWN0b3J5LiBJdCBpcyByZWNv
-bW1lbmRlZCB5b3UgY29tbWl0IGFueSBjaGFuZ2VzIHlvdSBtYWRlIGJlZm9yZSBkb2luZyB0aGlzLiIp
-KSlMLnR5KCIvYXBwbHktbWlncmF0aW9uIikuVzcobmV3IEwuanIoKSx1LlApLk9BKG5ldyBMLnFsKCkp
-fSwKJFM6M30KTC5qci5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdAp1LlMuYShhKQp0PWRv
-Y3VtZW50LmJvZHkKdC5jbGFzc0xpc3QucmVtb3ZlKCJwcm9wb3NlZCIpCnQuY2xhc3NMaXN0LmFkZCgi
-YXBwbGllZCIpfSwKJFM6NDB9CkwucWwucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXtMLkMyKCJD
-b3VsZCBub3QgYXBwbHkgbWlncmF0aW9uIixhLGIpfSwKJEM6IiQyIiwKJFI6MiwKJFM6Mn0KTC55OC5w
-cm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy54bih1LlYuYShhKSl9LAp4bjpmdW5j
-dGlvbihhKXt2YXIgdD0wLHM9UC5GWCh1LlApLHI9MSxxLHA9W10sbyxuLG0sbAp2YXIgJGFzeW5jJCQx
-PVAubHooZnVuY3Rpb24oYixjKXtpZihiPT09MSl7cT1jCnQ9cn13aGlsZSh0cnVlKXN3aXRjaCh0KXtj
-YXNlIDA6cj0zCmRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZCgicmVydW5uaW5nIikKdD02CnJldHVy
-biBQLmpRKEwudHkoIi9yZXJ1bi1taWdyYXRpb24iKSwkYXN5bmMkJDEpCmNhc2UgNjp3aW5kb3cubG9j
-YXRpb24ucmVsb2FkKCkKcC5wdXNoKDUpCnQ9NApicmVhawpjYXNlIDM6cj0yCmw9cQpvPUguUnUobCkK
-bj1ILnRzKGwpCkwuQzIoIkZhaWxlZCB0byByZXJ1biBtaWdyYXRpb24iLG8sbikKcC5wdXNoKDUpCnQ9
-NApicmVhawpjYXNlIDI6cD1bMV0KY2FzZSA0OnI9MQpkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5yZW1v
-dmUoInJlcnVubmluZyIpCnQ9cC5wb3AoKQpicmVhawpjYXNlIDU6cmV0dXJuIFAueUMobnVsbCxzKQpj
-YXNlIDE6cmV0dXJuIFAuZjMocSxzKX19KQpyZXR1cm4gUC5ESSgkYXN5bmMkJDEscyl9LAokUzo0MX0K
-TC5IaS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt1LlYuYShhKQpDLm9sLlBvKHdpbmRvdywiaHR0
-cHM6Ly9nb28uZ2xlL2RhcnQtbnVsbC1zYWZldHktbWlncmF0aW9uLXRvb2wtaXNzdWUiLCJyZXBvcnQt
-cHJvYmxlbSIpfSwKJFM6M30KTC5CVC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdAp1LlYu
-YShhKQp0PWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoIi5wb3B1cC1wYW5lIikuc3R5bGUKdC5kaXNwbGF5
-PSJub25lIgpyZXR1cm4ibm9uZSJ9LAokUzo0Mn0KTC5MLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEp
-e3ZhciB0LHMscgp1LkIuYShhKQp0PXdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZQpzPUwuRzYod2luZG93
-LmxvY2F0aW9uLmhyZWYpCnI9TC5hSyh3aW5kb3cubG9jYXRpb24uaHJlZikKaWYodC5sZW5ndGg+MSlM
-Lkc3KHQscyxyLCExLG51bGwpCmVsc2V7TC5CRSh0LG5ldyBCLnFwKCIiLCIiLCIiLEMuQ00pLCEwKQpM
-LkJYKCImbmJzcDsiLG51bGwpfX0sCiRTOjE3fQpMLld4LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEp
-e3ZhciB0LHMscixxPSJjb2xsYXBzZWQiCnUuVi5hKGEpCnQ9dGhpcy5hCnM9Si5SRSh0KQpyPXRoaXMu
-YgppZighcy5nUCh0KS50ZygwLHEpKXtzLmdQKHQpLmkoMCxxKQpKLmRSKHIpLmkoMCxxKX1lbHNle3Mu
-Z1AodCkuUigwLHEpCkouZFIocikuUigwLHEpfX0sCiRTOjN9CkwuQU8ucHJvdG90eXBlPXsKJDE6ZnVu
-Y3Rpb24oYSl7dmFyIHQ9Si5xRih1LmguYShhKSkscz10LiR0aSxyPXMuQygifigxKSIpLmEobmV3IEwu
-ZE4odGhpcy5hKSkKdS5NLmEobnVsbCkKVy5KRSh0LmEsdC5iLHIsITEscy5jKX0sCiRTOjV9CkwuZE4u
-cHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQKdS5WLmEoYSkKdD1kb2N1bWVudC5xdWVyeVNl
-bGVjdG9yKCJ0YWJsZVtkYXRhLXBhdGhdIikKdC50b1N0cmluZwpMLnQyKGEsdGhpcy5hLHQuZ2V0QXR0
-cmlidXRlKCJkYXRhLSIrbmV3IFcuU3kobmV3IFcuaTcodCkpLk8oInBhdGgiKSkpfSwKJFM6M30KTC5I
-by5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdCxzLHIKdS5oLmEoYSkKdD1KLnFGKGEpCnM9
-dC4kdGkKcj1zLkMoIn4oMSkiKS5hKG5ldyBMLnh6KGEsdGhpcy5hKSkKdS5NLmEobnVsbCkKVy5KRSh0
-LmEsdC5iLHIsITEscy5jKX0sCiRTOjV9CkwueHoucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFy
-IHQKdS5WLmEoYSkKdD10aGlzLmEKTC5oWCh0aGlzLmIsUC5RQSh0LmdldEF0dHJpYnV0ZSgiZGF0YS0i
+IikpCm49by4kdGkKVy5KRShvLmEsby5iLG4uQygifigxKT8iKS5hKG5ldyBMLkhpKCkpLCExLG4uYykK
+bj1KLnFGKHEucXVlcnlTZWxlY3RvcigiLnJlcG9ydC1wcm9ibGVtIikpCm89bi4kdGkKVy5KRShuLmEs
+bi5iLG8uQygifigxKT8iKS5hKG5ldyBMLkJUKCkpLCExLG8uYykKcT1KLnFGKHEucXVlcnlTZWxlY3Rv
+cigiLnBvcHVwLXBhbmUgLmNsb3NlIikpCm89cS4kdGkKVy5KRShxLmEscS5iLG8uQygifigxKT8iKS5h
+KG5ldyBMLlBZKCkpLCExLG8uYyl9LAokUzoxNn0KTC5WVy5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigp
+e0wuRnIodGhpcy5hLHRoaXMuYix0aGlzLmMpfSwKJFM6MH0KTC5vWi5wcm90b3R5cGU9ewokMTpmdW5j
+dGlvbihhKXt1Lk8uYShhKQppZihDLm9sLnVzKHdpbmRvdywiVGhpcyB3aWxsIGFwcGx5IHRoZSBjaGFu
+Z2VzIHlvdSd2ZSBwcmV2aWV3ZWQgdG8geW91ciB3b3JraW5nIGRpcmVjdG9yeS4gSXQgaXMgcmVjb21t
+ZW5kZWQgeW91IGNvbW1pdCBhbnkgY2hhbmdlcyB5b3UgbWFkZSBiZWZvcmUgZG9pbmcgdGhpcy4iKSlM
+LnR5KCIvYXBwbHktbWlncmF0aW9uIikuVzcobmV3IEwuanIoKSx1LlApLk9BKG5ldyBMLnFsKCkpfSwK
+JFM6M30KTC5qci5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdAp1LmEuYShhKQp0PWRvY3Vt
+ZW50LmJvZHkKdC5jbGFzc0xpc3QucmVtb3ZlKCJwcm9wb3NlZCIpCnQuY2xhc3NMaXN0LmFkZCgiYXBw
+bGllZCIpfSwKJFM6NDB9CkwucWwucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXtMLkMyKCJDb3Vs
+ZCBub3QgYXBwbHkgbWlncmF0aW9uIixhLGIpfSwKJEM6IiQyIiwKJFI6MiwKJFM6Mn0KTC5IaS5wcm90
+b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy54bih1Lk8uYShhKSl9LAp4bjpmdW5jdGlv
+bihhKXt2YXIgdD0wLHM9UC5GWCh1LlApLHI9MSxxLHA9W10sbyxuLG0sbAp2YXIgJGFzeW5jJCQxPVAu
+bHooZnVuY3Rpb24oYixjKXtpZihiPT09MSl7cT1jCnQ9cn13aGlsZSh0cnVlKXN3aXRjaCh0KXtjYXNl
+IDA6cj0zCmRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZCgicmVydW5uaW5nIikKdD02CnJldHVybiBQ
+LmpRKEwudHkoIi9yZXJ1bi1taWdyYXRpb24iKSwkYXN5bmMkJDEpCmNhc2UgNjp3aW5kb3cubG9jYXRp
+b24ucmVsb2FkKCkKcC5wdXNoKDUpCnQ9NApicmVhawpjYXNlIDM6cj0yCmw9cQpvPUguUnUobCkKbj1I
+LnRzKGwpCkwuQzIoIkZhaWxlZCB0byByZXJ1biBtaWdyYXRpb24iLG8sbikKcC5wdXNoKDUpCnQ9NApi
+cmVhawpjYXNlIDI6cD1bMV0KY2FzZSA0OnI9MQpkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5yZW1vdmUo
+InJlcnVubmluZyIpCnQ9cC5wb3AoKQpicmVhawpjYXNlIDU6cmV0dXJuIFAueUMobnVsbCxzKQpjYXNl
+IDE6cmV0dXJuIFAuZjMocSxzKX19KQpyZXR1cm4gUC5ESSgkYXN5bmMkJDEscyl9LAokUzo0MX0KTC5C
+VC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt1Lk8uYShhKQpDLm9sLlBvKHdpbmRvdywiaHR0cHM6
+Ly9nb28uZ2xlL2RhcnQtbnVsbC1zYWZldHktbWlncmF0aW9uLXRvb2wtaXNzdWUiLCJyZXBvcnQtcHJv
+YmxlbSIpfSwKJFM6M30KTC5QWS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdAp1Lk8uYShh
+KQp0PWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoIi5wb3B1cC1wYW5lIikuc3R5bGUKdC5kaXNwbGF5PSJu
+b25lIgpyZXR1cm4ibm9uZSJ9LAokUzo0Mn0KTC5MLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3Zh
+ciB0LHMscgp1LmFMLmEoYSkKdD13aW5kb3cubG9jYXRpb24ucGF0aG5hbWUKcz1MLkc2KHdpbmRvdy5s
+b2NhdGlvbi5ocmVmKQpyPUwuYUsod2luZG93LmxvY2F0aW9uLmhyZWYpCmlmKHQubGVuZ3RoPjEpTC5H
+Nyh0LHMsciwhMSxudWxsKQplbHNle0wuQkUodCxuZXcgQi5xcCgiIiwiIiwiIixDLkNNKSwhMCkKTC5C
+WCgiJm5ic3A7IixudWxsKX19LAokUzoxNn0KTC5XeC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2
+YXIgdCxzLHIscT0iY29sbGFwc2VkIgp1Lk8uYShhKQp0PXRoaXMuYQpzPUouWUUodCkKcj10aGlzLmIK
+aWYoIXMuZ1AodCkudGcoMCxxKSl7cy5nUCh0KS5pKDAscSkKSi5kUihyKS5pKDAscSl9ZWxzZXtzLmdQ
+KHQpLlIoMCxxKQpKLmRSKHIpLlIoMCxxKX19LAokUzozfQpMLkFPLnByb3RvdHlwZT17CiQxOmZ1bmN0
+aW9uKGEpe3ZhciB0PUoucUYodS5nLmEoYSkpLHM9dC4kdGkscj1zLkMoIn4oMSk/IikuYShuZXcgTC5k
+Tih0aGlzLmEpKQp1LlouYShudWxsKQpXLkpFKHQuYSx0LmIsciwhMSxzLmMpfSwKJFM6NH0KTC5kTi5w
+cm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdAp1Lk8uYShhKQp0PWRvY3VtZW50LnF1ZXJ5U2Vs
+ZWN0b3IoInRhYmxlW2RhdGEtcGF0aF0iKQp0LnRvU3RyaW5nCkwudDIoYSx0aGlzLmEsdC5nZXRBdHRy
+aWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyh0KSkuTygicGF0aCIpKSl9LAokUzozfQpMLkhv
+LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0LHMscgp1LmcuYShhKQp0PUoucUYoYSkKcz10
+LiR0aQpyPXMuQygifigxKT8iKS5hKG5ldyBMLnh6KGEsdGhpcy5hKSkKdS5aLmEobnVsbCkKVy5KRSh0
+LmEsdC5iLHIsITEscy5jKX0sCiRTOjR9CkwueHoucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFy
+IHQKdS5PLmEoYSkKdD10aGlzLmEKTC5oWCh0aGlzLmIsUC5RQSh0LmdldEF0dHJpYnV0ZSgiZGF0YS0i
K25ldyBXLlN5KG5ldyBXLmk3KHQpKS5PKCJvZmZzZXQiKSksbnVsbCksUC5RQSh0LmdldEF0dHJpYnV0
ZSgiZGF0YS0iK25ldyBXLlN5KG5ldyBXLmk3KHQpKS5PKCJsaW5lIikpLG51bGwpKX0sCiRTOjN9Ckwu
-SUMucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQ9Si5xRih1LmguYShhKSkscz10LiR0aQpz
-LkMoIn4oMSkiKS5hKEwuaVMoKSkKdS5NLmEobnVsbCkKVy5KRSh0LmEsdC5iLEwuaVMoKSwhMSxzLmMp
-fSwKJFM6NX0KTC5MMS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt1LnAuYShhKQp0aGlzLmEuYU0o
-MCx0aGlzLmIpfSwKJFM6MTR9CkwublQucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXtMLkZyKHRoaXMu
-YS5hLHRoaXMuYix0aGlzLmMpfSwKJFM6MH0KTC5OWS5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe0wu
-RnIodGhpcy5hLmEsbnVsbCxudWxsKX0sCiRTOjB9CkwuR0gucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24o
-YSl7dS5oLmEoYSkKJC56QigpLnRvU3RyaW5nCnUuaGIuYSgkLm93KCkucSgwLCJobGpzIikpLlY3KCJo
-aWdobGlnaHRCbG9jayIsW2FdKX0sCiRTOjV9CkwuRFQucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7
-dmFyIHQscwp1LnIuYShhKQp0PWEuc3RhdHVzCmlmKHQ9PT0yMDApe3Q9Qy5DdC5wVygwLGEucmVzcG9u
-c2VUZXh0LG51bGwpCnM9Si5VNih0KQpMLlQxKG5ldyBVLmQyKFUuamYocy5xKHQsImVkaXRzIikpLEgu
-YyhzLnEodCwiZXhwbGFuYXRpb24iKSksSC5XWShzLnEodCwibGluZSIpKSxILmMocy5xKHQsInBhdGgi
-KSksVS5OZChzLnEodCwidHJhY2VzIikpKSkKTC5Gcih0aGlzLmEsdGhpcy5iLHRoaXMuYykKTC55WCgi
-LmVkaXQtcGFuZWwgLnBhbmVsLWNvbnRlbnQiLCExKX1lbHNlIHdpbmRvdy5hbGVydCgiUmVxdWVzdCBm
-YWlsZWQ7IHN0YXR1cyBvZiAiK0guZCh0KSl9LAokUzo5fQpMLmVILnByb3RvdHlwZT17CiQyOmZ1bmN0
-aW9uKGEsYil7TC5xSigibG9hZFJlZ2lvbkV4cGxhbmF0aW9uOiAiK0guZChhKSxiKQp3aW5kb3cuYWxl
-cnQoIkNvdWxkIG5vdCBsb2FkICIrSC5kKHRoaXMuYSkrIiAoIitILmQoYSkrIikuIil9LAokQzoiJDIi
-LAokUjoyLAokUzoyfQpMLnl1LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0LHMscj10aGlz
-CnUuci5hKGEpCnQ9YS5zdGF0dXMKaWYodD09PTIwMCl7cz1yLmEKTC5CRShzLEIuWWYodS5iLmEoQy5D
-dC5wVygwLGEucmVzcG9uc2VUZXh0LG51bGwpKSksci5iKQp0PXIuYwpMLmZHKHQsci5kKQpMLkJYKEMu
-eEIudGcocywiPyIpP0MueEIuTmoocywwLEMueEIuT1kocywiPyIpKTpzLHQpCnQ9ci5lCmlmKHQhPW51
-bGwpdC4kMCgpfWVsc2Ugd2luZG93LmFsZXJ0KCJSZXF1ZXN0IGZhaWxlZDsgc3RhdHVzIG9mICIrSC5k
-KHQpKX0sCiRTOjl9CkwuekQucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXtMLnFKKCJsb2FkRmls
-ZTogIitILmQoYSksYikKd2luZG93LmFsZXJ0KCJDb3VsZCBub3QgbG9hZCAiK3RoaXMuYSsiICgiK0gu
-ZChhKSsiKS4iKX0sCiRDOiIkMiIsCiRSOjIsCiRTOjJ9CkwuVFcucHJvdG90eXBlPXsKJDE6ZnVuY3Rp
-b24oYSl7dmFyIHQscyxyCnUuci5hKGEpCnQ9YS5zdGF0dXMKaWYodD09PTIwMCl7cz1DLkN0LnBXKDAs
-YS5yZXNwb25zZVRleHQsbnVsbCkKcj1kb2N1bWVudC5xdWVyeVNlbGVjdG9yKCIubmF2LXRyZWUiKQpK
-Lmw1KHIsIiIpCkwudFgocixMLm1LKHMpKX1lbHNlIHdpbmRvdy5hbGVydCgiUmVxdWVzdCBmYWlsZWQ7
-IHN0YXR1cyBvZiAiK0guZCh0KSl9LAokUzo5fQpMLnhyLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEs
-Yil7TC5xSigibG9hZE5hdmlnYXRpb25UcmVlOiAiK0guZChhKSxiKQp3aW5kb3cuYWxlcnQoIkNvdWxk
-IG5vdCBsb2FkICIrdGhpcy5hKyIgKCIrSC5kKGEpKyIpLiIpfSwKJEM6IiQyIiwKJFI6MiwKJFM6Mn0K
-TC5FRS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdCxzCnUuVi5hKGEpCnQ9dGhpcy5hCnM9
-dGhpcy5iCkwuYWYod2luZG93LmxvY2F0aW9uLnBhdGhuYW1lLHQscywhMCxuZXcgTC5RTCh0LHMpKQpM
-LmhYKHRoaXMuYyx0LHMpfSwKJFM6M30KTC5RTC5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe0wuRnIo
-d2luZG93LmxvY2F0aW9uLnBhdGhuYW1lLHRoaXMuYSx0aGlzLmIpfSwKJFM6MH0KTC5WUy5wcm90b3R5
-cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdCxzPSJzZWxlY3RlZC1maWxlIgp1LmguYShhKQphLnRvU3Ry
-aW5nCnQ9Si5SRShhKQppZihhLmdldEF0dHJpYnV0ZSgiZGF0YS0iK25ldyBXLlN5KG5ldyBXLmk3KGEp
-KS5PKCJuYW1lIikpPT09dGhpcy5hLmEpdC5nUChhKS5pKDAscykKZWxzZSB0LmdQKGEpLlIoMCxzKX0s
-CiRTOjV9CkwuVEQucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIEwudDIodS5WLmEoYSks
-ITAsbnVsbCl9LAokUzoxOH0KTC5YQS5wcm90b3R5cGU9ewpFYjpmdW5jdGlvbihhLGIsYyl7cmV0dXJu
-ITB9LAppMDpmdW5jdGlvbihhKXtyZXR1cm4hMH0sCiRpa0Y6MX0KTC5aWi5wcm90b3R5cGU9e30KTC5P
-OS5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmJ9fQpNLmxJLnByb3RvdHlwZT17
-CldPOmZ1bmN0aW9uKGEsYil7dmFyIHQscz1udWxsCk0uWUYoImFic29sdXRlIixILlZNKFtiLG51bGws
-bnVsbCxudWxsLG51bGwsbnVsbCxudWxsXSx1LnMpKQp0PXRoaXMuYQp0PXQuWXIoYik+MCYmIXQuaEso
-YikKaWYodClyZXR1cm4gYgp0PUQuUlgoKQpyZXR1cm4gdGhpcy5xNygwLHQsYixzLHMscyxzLHMscyl9
-LAp0TTpmdW5jdGlvbihhKXt2YXIgdCxzLHI9WC5DTChhLHRoaXMuYSkKci5JVigpCnQ9ci5kCnM9dC5s
-ZW5ndGgKaWYocz09PTApe3Q9ci5iCnJldHVybiB0PT1udWxsPyIuIjp0fWlmKHM9PT0xKXt0PXIuYgpy
-ZXR1cm4gdD09bnVsbD8iLiI6dH1pZigwPj1zKXJldHVybiBILmsodCwtMSkKdC5wb3AoKQpDLk5tLm12
-KHIuZSkKci5JVigpCnJldHVybiByLlooMCl9LApxNzpmdW5jdGlvbihhLGIsYyxkLGUsZixnLGgsaSl7
-dmFyIHQ9SC5WTShbYixjLGQsZSxmLGcsaCxpXSx1LnMpCk0uWUYoImpvaW4iLHQpCnJldHVybiB0aGlz
-LklQKG5ldyBILlU1KHQsdS5iQi5hKG5ldyBNLk1pKCkpLHUuY2MpKX0sCklQOmZ1bmN0aW9uKGEpe3Zh
-ciB0LHMscixxLHAsbyxuLG0sbAp1LlguYShhKQpmb3IodD1hLiR0aSxzPXQuQygiYTIoY1guRSkiKS5h
-KG5ldyBNLnE3KCkpLHI9YS5na3ooYSksdD1uZXcgSC52RyhyLHMsdC5DKCJ2RzxjWC5FPiIpKSxzPXRo
-aXMuYSxxPSExLHA9ITEsbz0iIjt0LkYoKTspe249ci5nbCgpCmlmKHMuaEsobikmJnApe209WC5DTChu
-LHMpCmw9by5jaGFyQ29kZUF0KDApPT0wP286bwpvPUMueEIuTmoobCwwLHMuU3AobCwhMCkpCm0uYj1v
-CmlmKHMuZHMobykpQy5ObS5ZKG0uZSwwLHMuZ21JKCkpCm89bS5aKDApfWVsc2UgaWYocy5ZcihuKT4w
-KXtwPSFzLmhLKG4pCm89SC5kKG4pfWVsc2V7aWYoIShuLmxlbmd0aD4wJiZzLlVkKG5bMF0pKSlpZihx
-KW8rPXMuZ21JKCkKbys9SC5kKG4pfXE9cy5kcyhuKX1yZXR1cm4gby5jaGFyQ29kZUF0KDApPT0wP286
-b30sCm81OmZ1bmN0aW9uKGEpe3ZhciB0CmlmKCF0aGlzLnkzKGEpKXJldHVybiBhCnQ9WC5DTChhLHRo
-aXMuYSkKdC5yUigpCnJldHVybiB0LlooMCl9LAp5MzpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8s
-bixtLGwsawphLnRvU3RyaW5nCnQ9dGhpcy5hCnM9dC5ZcihhKQppZihzIT09MCl7aWYodD09PSQuS2so
-KSlmb3Iocj0wO3I8czsrK3IpaWYoQy54Qi5XKGEscik9PT00NylyZXR1cm4hMApxPXMKcD00N31lbHNl
-e3E9MApwPW51bGx9Zm9yKG89bmV3IEgucWooYSkuYSxuPW8ubGVuZ3RoLHI9cSxtPW51bGw7cjxuOysr
-cixtPXAscD1sKXtsPUMueEIubShvLHIpCmlmKHQucjQobCkpe2lmKHQ9PT0kLktrKCkmJmw9PT00Nyly
-ZXR1cm4hMAppZihwIT1udWxsJiZ0LnI0KHApKXJldHVybiEwCmlmKHA9PT00NilrPW09PW51bGx8fG09
-PT00Nnx8dC5yNChtKQplbHNlIGs9ITEKaWYoaylyZXR1cm4hMH19aWYocD09bnVsbClyZXR1cm4hMApp
-Zih0LnI0KHApKXJldHVybiEwCmlmKHA9PT00Nil0PW09PW51bGx8fHQucjQobSl8fG09PT00NgplbHNl
-IHQ9ITEKaWYodClyZXR1cm4hMApyZXR1cm4hMX0sCkhQOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEs
-cCxvPXRoaXMsbj0nVW5hYmxlIHRvIGZpbmQgYSBwYXRoIHRvICInCmI9by5XTygwLGIpCnQ9by5hCmlm
-KHQuWXIoYik8PTAmJnQuWXIoYSk+MClyZXR1cm4gby5vNShhKQppZih0LllyKGEpPD0wfHx0LmhLKGEp
-KWE9by5XTygwLGEpCmlmKHQuWXIoYSk8PTAmJnQuWXIoYik+MCl0aHJvdyBILmIoWC5JNyhuK0guZChh
-KSsnIiBmcm9tICInK0guZChiKSsnIi4nKSkKcz1YLkNMKGIsdCkKcy5yUigpCnI9WC5DTChhLHQpCnIu
-clIoKQpxPXMuZAppZihxLmxlbmd0aD4wJiZKLlJNKHFbMF0sIi4iKSlyZXR1cm4gci5aKDApCnE9cy5i
-CnA9ci5iCmlmKHEhPXApcT1xPT1udWxsfHxwPT1udWxsfHwhdC5OYyhxLHApCmVsc2UgcT0hMQppZihx
-KXJldHVybiByLlooMCkKd2hpbGUoITApe3E9cy5kCmlmKHEubGVuZ3RoPjApe3A9ci5kCnE9cC5sZW5n
-dGg+MCYmdC5OYyhxWzBdLHBbMF0pfWVsc2UgcT0hMQppZighcSlicmVhawpDLk5tLlc0KHMuZCwwKQpD
-Lk5tLlc0KHMuZSwxKQpDLk5tLlc0KHIuZCwwKQpDLk5tLlc0KHIuZSwxKX1xPXMuZAppZihxLmxlbmd0
-aD4wJiZKLlJNKHFbMF0sIi4uIikpdGhyb3cgSC5iKFguSTcobitILmQoYSkrJyIgZnJvbSAiJytILmQo
-YikrJyIuJykpCnE9dS5OCkMuTm0uVUcoci5kLDAsUC5POChzLmQubGVuZ3RoLCIuLiIsITEscSkpCkMu
-Tm0uWShyLmUsMCwiIikKQy5ObS5VRyhyLmUsMSxQLk84KHMuZC5sZW5ndGgsdC5nbUkoKSwhMSxxKSkK
-dD1yLmQKcT10Lmxlbmd0aAppZihxPT09MClyZXR1cm4iLiIKaWYocT4xJiZKLlJNKEMuTm0uZ3JaKHQp
-LCIuIikpe3Q9ci5kCmlmKDA+PXQubGVuZ3RoKXJldHVybiBILmsodCwtMSkKdC5wb3AoKQp0PXIuZQpD
-Lk5tLm12KHQpCkMuTm0ubXYodCkKQy5ObS5pKHQsIiIpfXIuYj0iIgpyLklWKCkKcmV0dXJuIHIuWigw
-KX19Ck0uTWkucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIEguYyhhKSE9bnVsbH0sCiRT
-Ojd9Ck0ucTcucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIEguYyhhKSE9PSIifSwKJFM6
-N30KTS5Oby5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtILmMoYSkKcmV0dXJuIGE9PW51bGw/Im51
-bGwiOiciJythKyciJ30sCiRTOjR9CkIuZnYucHJvdG90eXBlPXsKeFo6ZnVuY3Rpb24oYSl7dmFyIHQs
-cz10aGlzLllyKGEpCmlmKHM+MClyZXR1cm4gSi5sZChhLDAscykKaWYodGhpcy5oSyhhKSl7aWYoMD49
-YS5sZW5ndGgpcmV0dXJuIEguayhhLDApCnQ9YVswXX1lbHNlIHQ9bnVsbApyZXR1cm4gdH0sCk5jOmZ1
-bmN0aW9uKGEsYil7cmV0dXJuIGE9PWJ9fQpYLldELnByb3RvdHlwZT17CklWOmZ1bmN0aW9uKCl7dmFy
-IHQscyxyPXRoaXMKd2hpbGUoITApe3Q9ci5kCmlmKCEodC5sZW5ndGghPT0wJiZKLlJNKEMuTm0uZ3Ja
-KHQpLCIiKSkpYnJlYWsKdD1yLmQKaWYoMD49dC5sZW5ndGgpcmV0dXJuIEguayh0LC0xKQp0LnBvcCgp
-CkMuTm0ubXYoci5lKX10PXIuZQpzPXQubGVuZ3RoCmlmKHM+MClDLk5tLlkodCxzLTEsIiIpfSwKclI6
-ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwLG8sbixtPXRoaXMsbD1ILlZNKFtdLHUucykKZm9yKHQ9bS5k
-LHM9dC5sZW5ndGgscj0wLHE9MDtxPHQubGVuZ3RoO3QubGVuZ3RoPT09c3x8KDAsSC5saykodCksKytx
-KXtwPXRbcV0Kbz1KLmlhKHApCmlmKCEoby5ETihwLCIuIil8fG8uRE4ocCwiIikpKWlmKG8uRE4ocCwi
-Li4iKSlpZihsLmxlbmd0aD4wKWwucG9wKCkKZWxzZSArK3IKZWxzZSBDLk5tLmkobCxwKX1pZihtLmI9
-PW51bGwpQy5ObS5VRyhsLDAsUC5POChyLCIuLiIsITEsdS5OKSkKaWYobC5sZW5ndGg9PT0wJiZtLmI9
-PW51bGwpQy5ObS5pKGwsIi4iKQpuPVAuZEgobC5sZW5ndGgsbmV3IFgucVIobSksITAsdS5OKQp0PW0u
-Ygp0PXQhPW51bGwmJmwubGVuZ3RoPjAmJm0uYS5kcyh0KT9tLmEuZ21JKCk6IiIKSC50NihuKS5jLmEo
-dCkKaWYoISFuLmZpeGVkJGxlbmd0aClILnZoKFAuTDQoImluc2VydCIpKQpuLnNwbGljZSgwLDAsdCkK
-bS5zbkoobCkKbS5zUGgobikKdD1tLmIKaWYodCE9bnVsbCYmbS5hPT09JC5LaygpKXt0LnRvU3RyaW5n
-Cm0uYj1ILnlzKHQsIi8iLCJcXCIpfW0uSVYoKX0sClo6ZnVuY3Rpb24oYSl7dmFyIHQscyxyPXRoaXMs
-cT1yLmIKcT1xIT1udWxsP3E6IiIKZm9yKHQ9MDt0PHIuZC5sZW5ndGg7Kyt0KXtzPXIuZQppZih0Pj1z
-Lmxlbmd0aClyZXR1cm4gSC5rKHMsdCkKcz1xK0guZChzW3RdKQpxPXIuZAppZih0Pj1xLmxlbmd0aCly
-ZXR1cm4gSC5rKHEsdCkKcT1zK0guZChxW3RdKX1xKz1ILmQoQy5ObS5nclooci5lKSkKcmV0dXJuIHEu
-Y2hhckNvZGVBdCgwKT09MD9xOnF9LApzbko6ZnVuY3Rpb24oYSl7dGhpcy5kPXUuYS5hKGEpfSwKc1Bo
-OmZ1bmN0aW9uKGEpe3RoaXMuZT11LmEuYShhKX19ClgucVIucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24o
-YSl7cmV0dXJuIHRoaXMuYS5hLmdtSSgpfSwKJFM6NDZ9ClguZHYucHJvdG90eXBlPXsKWjpmdW5jdGlv
-bihhKXtyZXR1cm4iUGF0aEV4Y2VwdGlvbjogIit0aGlzLmF9fQpPLnpMLnByb3RvdHlwZT17Clo6ZnVu
-Y3Rpb24oYSl7cmV0dXJuIHRoaXMuZ29jKHRoaXMpfX0KRS5PRi5wcm90b3R5cGU9ewpVZDpmdW5jdGlv
-bihhKXtyZXR1cm4gQy54Qi50ZyhhLCIvIil9LApyNDpmdW5jdGlvbihhKXtyZXR1cm4gYT09PTQ3fSwK
-ZHM6ZnVuY3Rpb24oYSl7dmFyIHQ9YS5sZW5ndGgKcmV0dXJuIHQhPT0wJiZDLnhCLm0oYSx0LTEpIT09
-NDd9LApTcDpmdW5jdGlvbihhLGIpe2lmKGEubGVuZ3RoIT09MCYmQy54Qi5XKGEsMCk9PT00NylyZXR1
-cm4gMQpyZXR1cm4gMH0sCllyOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLlNwKGEsITEpfSwKaEs6ZnVu
-Y3Rpb24oYSl7cmV0dXJuITF9LApnb2M6ZnVuY3Rpb24oKXtyZXR1cm4icG9zaXgifSwKZ21JOmZ1bmN0
-aW9uKCl7cmV0dXJuIi8ifX0KRi5ydS5wcm90b3R5cGU9ewpVZDpmdW5jdGlvbihhKXtyZXR1cm4gQy54
-Qi50ZyhhLCIvIil9LApyNDpmdW5jdGlvbihhKXtyZXR1cm4gYT09PTQ3fSwKZHM6ZnVuY3Rpb24oYSl7
-dmFyIHQ9YS5sZW5ndGgKaWYodD09PTApcmV0dXJuITEKaWYoQy54Qi5tKGEsdC0xKSE9PTQ3KXJldHVy
-biEwCnJldHVybiBDLnhCLlRjKGEsIjovLyIpJiZ0aGlzLllyKGEpPT09dH0sClNwOmZ1bmN0aW9uKGEs
-Yil7dmFyIHQscyxyLHEscD1hLmxlbmd0aAppZihwPT09MClyZXR1cm4gMAppZihDLnhCLlcoYSwwKT09
-PTQ3KXJldHVybiAxCmZvcih0PTA7dDxwOysrdCl7cz1DLnhCLlcoYSx0KQppZihzPT09NDcpcmV0dXJu
-IDAKaWYocz09PTU4KXtpZih0PT09MClyZXR1cm4gMApyPUMueEIuWFUoYSwiLyIsQy54Qi5RaShhLCIv
-LyIsdCsxKT90KzM6dCkKaWYocjw9MClyZXR1cm4gcAppZighYnx8cDxyKzMpcmV0dXJuIHIKaWYoIUMu
-eEIubihhLCJmaWxlOi8vIikpcmV0dXJuIHIKaWYoIUIuWXUoYSxyKzEpKXJldHVybiByCnE9ciszCnJl
-dHVybiBwPT09cT9xOnIrNH19cmV0dXJuIDB9LApZcjpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5TcChh
-LCExKX0sCmhLOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aCE9PTAmJkMueEIuVyhhLDApPT09NDd9
-LApnb2M6ZnVuY3Rpb24oKXtyZXR1cm4idXJsIn0sCmdtSTpmdW5jdGlvbigpe3JldHVybiIvIn19Ckwu
-SVYucHJvdG90eXBlPXsKVWQ6ZnVuY3Rpb24oYSl7cmV0dXJuIEMueEIudGcoYSwiLyIpfSwKcjQ6ZnVu
-Y3Rpb24oYSl7cmV0dXJuIGE9PT00N3x8YT09PTkyfSwKZHM6ZnVuY3Rpb24oYSl7dmFyIHQ9YS5sZW5n
-dGgKaWYodD09PTApcmV0dXJuITEKdD1DLnhCLm0oYSx0LTEpCnJldHVybiEodD09PTQ3fHx0PT09OTIp
-fSwKU3A6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9YS5sZW5ndGgKaWYocj09PTApcmV0dXJuIDAKdD1D
-LnhCLlcoYSwwKQppZih0PT09NDcpcmV0dXJuIDEKaWYodD09PTkyKXtpZihyPDJ8fEMueEIuVyhhLDEp
-IT09OTIpcmV0dXJuIDEKcz1DLnhCLlhVKGEsIlxcIiwyKQppZihzPjApe3M9Qy54Qi5YVShhLCJcXCIs
-cysxKQppZihzPjApcmV0dXJuIHN9cmV0dXJuIHJ9aWYocjwzKXJldHVybiAwCmlmKCFCLk9TKHQpKXJl
-dHVybiAwCmlmKEMueEIuVyhhLDEpIT09NTgpcmV0dXJuIDAKcj1DLnhCLlcoYSwyKQppZighKHI9PT00
-N3x8cj09PTkyKSlyZXR1cm4gMApyZXR1cm4gM30sCllyOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLlNw
-KGEsITEpfSwKaEs6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuWXIoYSk9PT0xfSwKT3Q6ZnVuY3Rpb24o
-YSxiKXt2YXIgdAppZihhPT09YilyZXR1cm4hMAppZihhPT09NDcpcmV0dXJuIGI9PT05MgppZihhPT09
-OTIpcmV0dXJuIGI9PT00NwppZigoYV5iKSE9PTMyKXJldHVybiExCnQ9YXwzMgpyZXR1cm4gdD49OTcm
-JnQ8PTEyMn0sCk5jOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyCmlmKGE9PWIpcmV0dXJuITAKdD1hLmxl
-bmd0aAppZih0IT09Yi5sZW5ndGgpcmV0dXJuITEKZm9yKHM9Si5yWShiKSxyPTA7cjx0OysrcilpZigh
-dGhpcy5PdChDLnhCLlcoYSxyKSxzLlcoYixyKSkpcmV0dXJuITEKcmV0dXJuITB9LApnb2M6ZnVuY3Rp
-b24oKXtyZXR1cm4id2luZG93cyJ9LApnbUk6ZnVuY3Rpb24oKXtyZXR1cm4iXFwifX07KGZ1bmN0aW9u
-IGFsaWFzZXMoKXt2YXIgdD1KLnZCLnByb3RvdHlwZQp0LlU9dC5aCnQuU2o9dC5lNwp0PUouTUYucHJv
-dG90eXBlCnQudD10LloKdD1QLmNYLnByb3RvdHlwZQp0LkdHPXQuZXYKdD1QLk1oLnByb3RvdHlwZQp0
-LnhiPXQuWgp0PVcuY3YucHJvdG90eXBlCnQuRFc9dC5yNgp0PVcubTYucHJvdG90eXBlCnQuakY9dC5F
-Ygp0PVAuRTQucHJvdG90eXBlCnQuVXI9dC5xCnQuZTQ9dC5ZfSkoKTsoZnVuY3Rpb24gaW5zdGFsbFRl
-YXJPZmZzKCl7dmFyIHQ9aHVua0hlbHBlcnMuX3N0YXRpY18xLHM9aHVua0hlbHBlcnMuX3N0YXRpY18w
-LHI9aHVua0hlbHBlcnMuaW5zdGFsbEluc3RhbmNlVGVhck9mZixxPWh1bmtIZWxwZXJzLmluc3RhbGxT
-dGF0aWNUZWFyT2ZmLHA9aHVua0hlbHBlcnMuX2luc3RhbmNlXzF1CnQoUCwiRVgiLCJaViIsMTApCnQo
-UCwieXQiLCJvQSIsMTApCnQoUCwicVciLCJCeiIsMTApCnMoUCwiVjkiLCJlTiIsMSkKcihQLlBmLnBy
-b3RvdHlwZSwiZ1lKIiwwLDEsbnVsbCxbIiQyIiwiJDEiXSxbIncwIiwicG0iXSwzMiwwKQp0KFAsIlBI
-IiwiTXQiLDQpCnEoVywicFMiLDQsbnVsbCxbIiQ0Il0sWyJ5VyJdLDExLDApCnEoVywiVjQiLDQsbnVs
-bCxbIiQ0Il0sWyJRVyJdLDExLDApCnAoUC5Bcy5wcm90b3R5cGUsImd1TSIsIlQiLDQpCnQoUCwiaUci
-LCJ3WSIsNDkpCnQoUCwidzAiLCJMNyIsMzMpCnQoTCwiaVMiLCJpNiIsMTgpfSkoKTsoZnVuY3Rpb24g
-aW5oZXJpdGFuY2UoKXt2YXIgdD1odW5rSGVscGVycy5taXhpbixzPWh1bmtIZWxwZXJzLmluaGVyaXQs
-cj1odW5rSGVscGVycy5pbmhlcml0TWFueQpzKFAuTWgsbnVsbCkKcihQLk1oLFtILkZLLEoudkIsSi5t
-MSxQLlhTLFAublksUC5jWCxILmE3LFAuQW4sSC5TVSxILlJlLEgud3YsUC5QbixILldVLEguTEksSC5U
-cCxILmY5LEguYnEsSC5YTyxQLllrLEguZGIsSC5ONixILlZSLEguRUssSC5QYixILnRRLEguU2QsSC5K
-YyxILkVULFAuVzMsUC5paCxQLkZ5LFAuR1YsUC5iOCxQLlBmLFAuRmUsUC52cyxQLk9NLFAucWgsUC5N
-TyxQLmtULFAueEksUC5PSCxQLm0wLFAuWHYsUC5ibixQLmxtLFAubEQsUC5LUCxQLk1hLFAuVEMsUC5V
-ayxQLlJ3LFAuYnosUC5hMixQLmlQLFAubGYsUC5rNSxQLktZLFAuQ0QsUC5hRSxQLkVILFAuek0sUC5a
-MCxQLk4zLFAuYzgsUC5PZCxQLmliLFAuR3osUC5aZCxQLnFVLFAuUm4sUC5HRCxQLkRuLFAuUEUsUC5V
-ZixXLmlkLFcuRmssVy5KUSxXLkdtLFcudkQsVy5tNixXLk93LFcuVzksVy5kVyxXLkZiLFcua0YsVy5t
-ayxXLktvLFAuaUosUC5FNCxQLm42LFUuZDIsVS5TZSxVLk1sLFUueUQsVS53YixCLmo4LEIucXAsVC5t
-USxMLlhBLEwuWlosTC5POSxNLmxJLE8uekwsWC5XRCxYLmR2XSkKcihKLnZCLFtKLnlFLEouWUUsSi5N
-RixKLmpkLEoucUksSi5EcixILnBGLFcuRDAsVy5BeixXLkxlLFcuTmgsVy5JQixXLm43LFcuZWEsVy5i
-cixXLlNnLFcudTgsVy5LNyxXLlhXLFAuaEZdKQpyKEouTUYsW0ouaUMsSi5rZCxKLmM1XSkKcyhKLlBv
-LEouamQpCnIoSi5xSSxbSi51cixKLlZBXSkKcihQLlhTLFtILm5kLEguVzAsSC5heixILnZWLEguRXEs
-UC5DNixILnU5LFAuTEssUC5BVCxQLm1wLFAudWIsUC5kcyxQLmxqLFAuVVYsUC50N10pCnMoUC5MVSxQ
-Lm5ZKQpyKFAuTFUsW0gudzIsVy53eixXLmU3XSkKcyhILnFqLEgudzIpCnIoUC5jWCxbSC5iUSxILmkx
-LEguVTUsSC5YUixQLm1XLEguTkZdKQpyKEguYlEsW0guYUwsSC5pNSxQLnh1XSkKcihILmFMLFtILm5I
-LEgubEosUC5pOF0pCnMoSC54eSxILmkxKQpyKFAuQW4sW0guTUgsSC52R10pCnMoUC5SVSxQLlBuKQpz
-KFAuR2osUC5SVSkKcyhILlBELFAuR2opCnMoSC5MUCxILldVKQpyKEguVHAsW0guQ2osSC5BbSxILmxj
-LEgucixILmRDLEgud04sUC50aCxQLmhhLFAuVnMsUC5GdCxQLnlILFAuV00sUC5TWCxQLkdzLFAuZGEs
-UC5vUSxQLnBWLFAuVTcsUC52cixQLnJILFAuS0YsUC5aTCxQLlJULFAualosUC5ycSxQLlJXLFAuQjUs
-UC51TyxQLnBLLFAuaGosUC5WcCxQLk9SLFAucmEsUC55USxQLnBnLFAuV0YsUC5uMSxQLmNTLFAuVkMs
-UC5KVCxQLlJaLFAuTUUsUC55NSxQLnEzLFAueUksUC5jNixQLnFkLFcuQ3YsVy5iVSxXLmhILFcuS1Ms
-Vy5BMyxXLnZOLFcuVXYsVy5FZyxXLkVvLFcuV2ssVy5JQSxXLmZtLFAuamcsUC5UYSxQLkdFLFAuTjcs
-UC51USxQLlBDLFAubXQsUC5OeixQLlFTLFAubnAsTC5lLEwuVlcsTC5vWixMLmpyLEwucWwsTC55OCxM
-LkhpLEwuQlQsTC5MLEwuV3gsTC5BTyxMLmROLEwuSG8sTC54eixMLklDLEwuTDEsTC5uVCxMLk5ZLEwu
-R0gsTC5EVCxMLmVILEwueXUsTC56RCxMLlRXLEwueHIsTC5FRSxMLlFMLEwuVlMsTC5URCxNLk1pLE0u
-cTcsTS5ObyxYLnFSXSkKcihILmxjLFtILnp4LEguanldKQpzKEgua1ksUC5DNikKcyhQLmlsLFAuWWsp
-CnIoUC5pbCxbSC5ONSxQLnV3LFcuY2YsVy5TeV0pCnIoUC5tVyxbSC5LVyxQLnE0XSkKcyhILmIwLEgu
-cEYpCnIoSC5iMCxbSC5SRyxILldCXSkKcyhILlZQLEguUkcpCnMoSC5EZyxILlZQKQpzKEguWkcsSC5X
-QikKcyhILlBnLEguWkcpCnIoSC5QZyxbSC54aixILmRFLEguWkEsSC53ZixILlBxLEguZUUsSC5WNl0p
-CnMoSC54LEgudTkpCnMoUC5aZixQLlBmKQpzKFAuSmksUC5tMCkKcyhQLmI2LFAuWHYpCnMoUC5WaixQ
-LlRDKQpyKFAuVWssW1AuQ1YsUC5aaSxQLmJ5XSkKcyhQLndJLFAua1QpCnIoUC53SSxbUC5VOCxQLk14
-LFAuRTMsUC5HWV0pCnMoUC51NSxQLlppKQpyKFAubGYsW1AuQ1AsUC5JZl0pCnIoUC5BVCxbUC5iSixQ
-LmVZXSkKcyhQLnFlLFAuRG4pCnIoVy5EMCxbVy51SCxXLndhLFcuSzUsVy5DbV0pCnIoVy51SCxbVy5j
-dixXLm54LFcuUUYsVy5DUV0pCnIoVy5jdixbVy5xRSxQLmQ1XSkKcihXLnFFLFtXLkdoLFcuZlksVy5u
-QixXLlFQLFcuaDQsVy5TTixXLmxwLFcuVGIsVy5JdixXLldQLFcueVldKQpzKFcub0osVy5MZSkKcyhX
-LlQ1LFcuQXopCnMoVy5WYixXLlFGKQpzKFcuZkosVy53YSkKcihXLmVhLFtXLnc2LFcuZXddKQpzKFcu
-T0ssVy53NikKcyhXLnJCLFcuSzcpCnMoVy5CSCxXLnJCKQpzKFcudzQsVy5JQikKcyhXLm9hLFcuWFcp
-CnMoVy5yaCxXLm9hKQpzKFcuaTcsVy5jZikKcyhQLkFzLFAuVmopCnIoUC5BcyxbVy5JNCxQLktlXSkK
-cyhXLlJPLFAucWgpCnMoVy5ldSxXLlJPKQpzKFcueEMsUC5NTykKcyhXLmN0LFcubTYpCnMoUC5CZixQ
-LmlKKQpyKFAuRTQsW1AucjcsUC5jb10pCnMoUC5UeixQLmNvKQpzKFAuYkIsUC5kNSkKcyhCLmZ2LE8u
-ekwpCnIoQi5mdixbRS5PRixGLnJ1LEwuSVZdKQp0KEgudzIsSC5SZSkKdChILlJHLFAubEQpCnQoSC5W
-UCxILlNVKQp0KEguV0IsUC5sRCkKdChILlpHLEguU1UpCnQoUC5uWSxQLmxEKQp0KFAuVEMsUC5NYSkK
-dChQLlJVLFAuS1ApCnQoVy5MZSxXLmlkKQp0KFcuSzcsUC5sRCkKdChXLnJCLFcuR20pCnQoVy5YVyxQ
-LmxEKQp0KFcub2EsVy5HbSkKdChQLmNvLFAubEQpfSkoKQp2YXIgdj17dHlwZVVuaXZlcnNlOntlQzpu
-ZXcgTWFwKCksdFI6e30sZVQ6e30sdFBWOnt9LHNFQTpbXX0sbWFuZ2xlZEdsb2JhbE5hbWVzOntJZjoi
-aW50IixDUDoiZG91YmxlIixsZjoibnVtIixxVToiU3RyaW5nIixhMjoiYm9vbCIsYzg6Ik51bGwiLHpN
-OiJMaXN0In0sbWFuZ2xlZE5hbWVzOnt9LGdldFR5cGVGcm9tTmFtZTpnZXRHbG9iYWxGcm9tTmFtZSxt
-ZXRhZGF0YTpbXSx0eXBlczpbImM4KCkiLCJ+KCkiLCJjOChALEApIiwiYzgoT0spIiwicVUocVUpIiwi
-YzgoY3YpIiwiQChAKSIsImEyKHFVKSIsImM4KHFVLHFVKSIsImM4KGZKKSIsIn4ofigpKSIsImEyKGN2
-LHFVLHFVLEpRKSIsImM4KEApIiwiYzgocVUsQCkiLCJjOChldykiLCJhMihrRikiLCJ+KHh1PHFVPiki
-LCJjOChlYSkiLCJ+KE9LKSIsIlowPHFVLHFVPihaMDxxVSxxVT4scVUpIiwiSWYoSWYsSWYpIiwiQChx
-VSkiLCJ+KHFVLHFVKSIsIm42KElmKSIsIm42KEAsQCkiLCJhMih1SCkiLCJAKEAscVUpIiwifihAKSIs
-IkAoZWEpIiwiYzgoQCxHeikiLCJjOChJZixAKSIsIn4odUgsdUgpIiwifihNaFtHel0pIiwiTWgoQCki
-LCJjOChNaCxHeikiLCJyNyhAKSIsIlR6PEA+KEApIiwiRTQoQCkiLCJ2czxAPihAKSIsImM4KE1oLE1o
-KSIsImM4KFowPHFVLE1oPikiLCJiODxjOD4oT0spIiwicVUoT0spIiwiQCgpIiwiYzgoR0QsQCkiLCJj
-OCh+KCkpIiwicVUoSWYpIiwifihxVSxJZikiLCJ+KHFVW0BdKSIsIk1oKE1oKSIsImEyKHh1PHFVPiki
-XSxpbnRlcmNlcHRvcnNCeVRhZzpudWxsLGxlYWZUYWdzOm51bGwsYXJyYXlSdGk6dHlwZW9mIFN5bWJv
-bD09ImZ1bmN0aW9uIiYmdHlwZW9mIFN5bWJvbCgpPT0ic3ltYm9sIj9TeW1ib2woIiR0aSIpOiIkdGki
-fQpILnhiKHYudHlwZVVuaXZlcnNlLEpTT04ucGFyc2UoJ3siYzUiOiJNRiIsImlDIjoiTUYiLCJrZCI6
-Ik1GIiwicngiOiJlYSIsImU1IjoiZWEiLCJZMCI6ImQ1IiwidHAiOiJkNSIsIkc4IjoiZXciLCJNciI6
-InFFIiwiZUwiOiJxRSIsIkkwIjoidUgiLCJocyI6InVIIiwiWGciOiJRRiIsInljIjoiT0siLCJ5NCI6
-Inc2IiwiYVAiOiJDbSIsInhjIjoibngiLCJrSiI6Im54IiwielUiOiJEZyIsImRmIjoicEYiLCJ5RSI6
-eyJhMiI6W119LCJZRSI6eyJjOCI6W119LCJNRiI6eyJ2bSI6W10sIkVIIjpbXX0sImpkIjp7InpNIjpb
-IjEiXSwiYlEiOlsiMSJdLCJjWCI6WyIxIl19LCJQbyI6eyJqZCI6WyIxIl0sInpNIjpbIjEiXSwiYlEi
-OlsiMSJdLCJjWCI6WyIxIl19LCJtMSI6eyJBbiI6WyIxIl19LCJxSSI6eyJDUCI6W10sImxmIjpbXX0s
-InVyIjp7IklmIjpbXSwiQ1AiOltdLCJsZiI6W119LCJWQSI6eyJDUCI6W10sImxmIjpbXX0sIkRyIjp7
-InFVIjpbXSwidlgiOltdfSwibmQiOnsiWFMiOltdfSwicWoiOnsiUmUiOlsiSWYiXSwibEQiOlsiSWYi
-XSwiek0iOlsiSWYiXSwiYlEiOlsiSWYiXSwiY1giOlsiSWYiXSwibEQuRSI6IklmIiwiUmUuRSI6Iklm
-In0sImJRIjp7ImNYIjpbIjEiXX0sImFMIjp7ImJRIjpbIjEiXSwiY1giOlsiMSJdfSwibkgiOnsiYUwi
-OlsiMSJdLCJiUSI6WyIxIl0sImNYIjpbIjEiXSwiYUwuRSI6IjEiLCJjWC5FIjoiMSJ9LCJhNyI6eyJB
-biI6WyIxIl19LCJpMSI6eyJjWCI6WyIyIl0sImNYLkUiOiIyIn0sInh5Ijp7ImkxIjpbIjEiLCIyIl0s
-ImJRIjpbIjIiXSwiY1giOlsiMiJdLCJjWC5FIjoiMiJ9LCJNSCI6eyJBbiI6WyIyIl19LCJsSiI6eyJh
-TCI6WyIyIl0sImJRIjpbIjIiXSwiY1giOlsiMiJdLCJhTC5FIjoiMiIsImNYLkUiOiIyIn0sIlU1Ijp7
-ImNYIjpbIjEiXSwiY1guRSI6IjEifSwidkciOnsiQW4iOlsiMSJdfSwidzIiOnsiUmUiOlsiMSJdLCJs
-RCI6WyIxIl0sInpNIjpbIjEiXSwiYlEiOlsiMSJdLCJjWCI6WyIxIl19LCJ3diI6eyJHRCI6W119LCJQ
-RCI6eyJHaiI6WyIxIiwiMiJdLCJSVSI6WyIxIiwiMiJdLCJQbiI6WyIxIiwiMiJdLCJLUCI6WyIxIiwi
-MiJdLCJaMCI6WyIxIiwiMiJdfSwiV1UiOnsiWjAiOlsiMSIsIjIiXX0sIkxQIjp7IldVIjpbIjEiLCIy
-Il0sIlowIjpbIjEiLCIyIl19LCJYUiI6eyJjWCI6WyIxIl0sImNYLkUiOiIxIn0sIkxJIjp7InZRIjpb
-XX0sIlcwIjp7IlhTIjpbXX0sImF6Ijp7IlhTIjpbXX0sInZWIjp7IlhTIjpbXX0sIlhPIjp7Ikd6Ijpb
-XX0sIlRwIjp7IkVIIjpbXX0sImxjIjp7IkVIIjpbXX0sInp4Ijp7IkVIIjpbXX0sImp5Ijp7IkVIIjpb
-XX0sIkVxIjp7IlhTIjpbXX0sImtZIjp7IlhTIjpbXX0sIk41Ijp7IkZvIjpbIjEiLCIyIl0sIllrIjpb
-IjEiLCIyIl0sIlowIjpbIjEiLCIyIl0sIllrLksiOiIxIiwiWWsuViI6IjIifSwiaTUiOnsiYlEiOlsi
-MSJdLCJjWCI6WyIxIl0sImNYLkUiOiIxIn0sIk42Ijp7IkFuIjpbIjEiXX0sIlZSIjp7IndMIjpbXSwi
-dlgiOltdfSwiRUsiOnsiaWIiOltdLCJPZCI6W119LCJLVyI6eyJjWCI6WyJpYiJdLCJjWC5FIjoiaWIi
-fSwiUGIiOnsiQW4iOlsiaWIiXX0sInRRIjp7Ik9kIjpbXX0sIk5GIjp7ImNYIjpbIk9kIl0sImNYLkUi
-OiJPZCJ9LCJTZCI6eyJBbiI6WyJPZCJdfSwicEYiOnsiQVMiOltdfSwiYjAiOnsiWGoiOlsiMSJdLCJw
-RiI6W10sIkFTIjpbXX0sIkRnIjp7ImxEIjpbIkNQIl0sIlhqIjpbIkNQIl0sInpNIjpbIkNQIl0sInBG
-IjpbXSwiYlEiOlsiQ1AiXSwiU1UiOlsiQ1AiXSwiQVMiOltdLCJjWCI6WyJDUCJdLCJsRC5FIjoiQ1Ai
-fSwiUGciOnsibEQiOlsiSWYiXSwiek0iOlsiSWYiXSwiWGoiOlsiSWYiXSwicEYiOltdLCJiUSI6WyJJ
-ZiJdLCJTVSI6WyJJZiJdLCJBUyI6W10sImNYIjpbIklmIl19LCJ4aiI6eyJsRCI6WyJJZiJdLCJ6TSI6
-WyJJZiJdLCJYaiI6WyJJZiJdLCJwRiI6W10sImJRIjpbIklmIl0sIlNVIjpbIklmIl0sIkFTIjpbXSwi
-Y1giOlsiSWYiXSwibEQuRSI6IklmIn0sImRFIjp7ImxEIjpbIklmIl0sInpNIjpbIklmIl0sIlhqIjpb
-IklmIl0sInBGIjpbXSwiYlEiOlsiSWYiXSwiU1UiOlsiSWYiXSwiQVMiOltdLCJjWCI6WyJJZiJdLCJs
-RC5FIjoiSWYifSwiWkEiOnsibEQiOlsiSWYiXSwiek0iOlsiSWYiXSwiWGoiOlsiSWYiXSwicEYiOltd
-LCJiUSI6WyJJZiJdLCJTVSI6WyJJZiJdLCJBUyI6W10sImNYIjpbIklmIl0sImxELkUiOiJJZiJ9LCJ3
-ZiI6eyJsRCI6WyJJZiJdLCJ6TSI6WyJJZiJdLCJYaiI6WyJJZiJdLCJwRiI6W10sImJRIjpbIklmIl0s
-IlNVIjpbIklmIl0sIkFTIjpbXSwiY1giOlsiSWYiXSwibEQuRSI6IklmIn0sIlBxIjp7ImxEIjpbIklm
-Il0sInpNIjpbIklmIl0sIlhqIjpbIklmIl0sInBGIjpbXSwiYlEiOlsiSWYiXSwiU1UiOlsiSWYiXSwi
-QVMiOltdLCJjWCI6WyJJZiJdLCJsRC5FIjoiSWYifSwiZUUiOnsibEQiOlsiSWYiXSwiek0iOlsiSWYi
-XSwiWGoiOlsiSWYiXSwicEYiOltdLCJiUSI6WyJJZiJdLCJTVSI6WyJJZiJdLCJBUyI6W10sImNYIjpb
-IklmIl0sImxELkUiOiJJZiJ9LCJWNiI6eyJuNiI6W10sImxEIjpbIklmIl0sInpNIjpbIklmIl0sIlhq
-IjpbIklmIl0sInBGIjpbXSwiYlEiOlsiSWYiXSwiU1UiOlsiSWYiXSwiQVMiOltdLCJjWCI6WyJJZiJd
-LCJsRC5FIjoiSWYifSwidTkiOnsiWFMiOltdfSwieCI6eyJYUyI6W119LCJHViI6eyJBbiI6WyIxIl19
-LCJxNCI6eyJjWCI6WyIxIl0sImNYLkUiOiIxIn0sIlpmIjp7IlBmIjpbIjEiXX0sInZzIjp7ImI4Ijpb
-IjEiXX0sIk9IIjp7IlhTIjpbXX0sIm0wIjp7IkpCIjpbXX0sIkppIjp7Im0wIjpbXSwiSkIiOltdfSwi
-YjYiOnsiWHYiOlsiMSJdLCJ4dSI6WyIxIl0sImJRIjpbIjEiXSwiY1giOlsiMSJdfSwibG0iOnsiQW4i
-OlsiMSJdfSwibVciOnsiY1giOlsiMSJdfSwiTFUiOnsibEQiOlsiMSJdLCJ6TSI6WyIxIl0sImJRIjpb
-IjEiXSwiY1giOlsiMSJdfSwiaWwiOnsiWWsiOlsiMSIsIjIiXSwiWjAiOlsiMSIsIjIiXX0sIllrIjp7
-IlowIjpbIjEiLCIyIl19LCJQbiI6eyJaMCI6WyIxIiwiMiJdfSwiR2oiOnsiUlUiOlsiMSIsIjIiXSwi
-UG4iOlsiMSIsIjIiXSwiS1AiOlsiMSIsIjIiXSwiWjAiOlsiMSIsIjIiXX0sIlZqIjp7Ik1hIjpbIjEi
-XSwieHUiOlsiMSJdLCJiUSI6WyIxIl0sImNYIjpbIjEiXX0sIlh2Ijp7Inh1IjpbIjEiXSwiYlEiOlsi
-MSJdLCJjWCI6WyIxIl19LCJ1dyI6eyJZayI6WyJxVSIsIkAiXSwiWjAiOlsicVUiLCJAIl0sIllrLksi
-OiJxVSIsIllrLlYiOiJAIn0sImk4Ijp7ImFMIjpbInFVIl0sImJRIjpbInFVIl0sImNYIjpbInFVIl0s
-ImFMLkUiOiJxVSIsImNYLkUiOiJxVSJ9LCJDViI6eyJVayI6WyJ6TTxJZj4iLCJxVSJdLCJVay5TIjoi
-ek08SWY+In0sIlU4Ijp7IndJIjpbInpNPElmPiIsInFVIl19LCJaaSI6eyJVayI6WyJxVSIsInpNPElm
-PiJdfSwiYnkiOnsiVWsiOlsiTWgiLCJxVSJdLCJVay5TIjoiTWgifSwiTXgiOnsid0kiOlsicVUiLCJN
-aCJdfSwidTUiOnsiVWsiOlsicVUiLCJ6TTxJZj4iXSwiVWsuUyI6InFVIn0sIkUzIjp7IndJIjpbInFV
-Iiwiek08SWY+Il19LCJHWSI6eyJ3SSI6WyJ6TTxJZj4iLCJxVSJdfSwiQ1AiOnsibGYiOltdfSwiQzYi
-OnsiWFMiOltdfSwiTEsiOnsiWFMiOltdfSwiQVQiOnsiWFMiOltdfSwiYkoiOnsiWFMiOltdfSwiZVki
-OnsiWFMiOltdfSwibXAiOnsiWFMiOltdfSwidWIiOnsiWFMiOltdfSwiZHMiOnsiWFMiOltdfSwibGoi
-OnsiWFMiOltdfSwiVVYiOnsiWFMiOltdfSwiazUiOnsiWFMiOltdfSwiS1kiOnsiWFMiOltdfSwidDci
-OnsiWFMiOltdfSwiSWYiOnsibGYiOltdfSwiek0iOnsiYlEiOlsiMSJdLCJjWCI6WyIxIl19LCJpYiI6
-eyJPZCI6W119LCJ4dSI6eyJiUSI6WyIxIl0sImNYIjpbIjEiXX0sIlpkIjp7Ikd6IjpbXX0sInFVIjp7
-InZYIjpbXX0sIlJuIjp7IkJMIjpbXX0sIkRuIjp7ImlEIjpbXX0sIlVmIjp7ImlEIjpbXX0sInFlIjp7
-ImlEIjpbXX0sInFFIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJHaCI6eyJjdiI6W10sInVIIjpb
-XSwiRDAiOltdfSwiZlkiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIm5CIjp7ImN2IjpbXSwidUgi
-OltdLCJEMCI6W119LCJRUCI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwibngiOnsidUgiOltdLCJE
-MCI6W119LCJRRiI6eyJ1SCI6W10sIkQwIjpbXX0sIklCIjp7InRuIjpbImxmIl19LCJ3eiI6eyJsRCI6
-WyIxIl0sInpNIjpbIjEiXSwiYlEiOlsiMSJdLCJjWCI6WyIxIl0sImxELkUiOiIxIn0sImN2Ijp7InVI
-IjpbXSwiRDAiOltdfSwiVDUiOnsiQXoiOltdfSwiaDQiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0s
-IlZiIjp7InVIIjpbXSwiRDAiOltdfSwiZkoiOnsiRDAiOltdfSwid2EiOnsiRDAiOltdfSwiT0siOnsi
-ZWEiOltdfSwiZTciOnsibEQiOlsidUgiXSwiek0iOlsidUgiXSwiYlEiOlsidUgiXSwiY1giOlsidUgi
-XSwibEQuRSI6InVIIn0sInVIIjp7IkQwIjpbXX0sIkJIIjp7IkdtIjpbInVIIl0sImxEIjpbInVIIl0s
-InpNIjpbInVIIl0sIlhqIjpbInVIIl0sImJRIjpbInVIIl0sImNYIjpbInVIIl0sIkdtLkUiOiJ1SCIs
-ImxELkUiOiJ1SCJ9LCJTTiI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiZXciOnsiZWEiOltdfSwi
-bHAiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIlRiIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119
-LCJJdiI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiV1AiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpb
-XX0sInlZIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJ3NiI6eyJlYSI6W119LCJLNSI6eyJ2NiI6
-W10sIkQwIjpbXX0sIkNtIjp7IkQwIjpbXX0sIkNRIjp7InVIIjpbXSwiRDAiOltdfSwidzQiOnsidG4i
-OlsibGYiXX0sInJoIjp7IkdtIjpbInVIIl0sImxEIjpbInVIIl0sInpNIjpbInVIIl0sIlhqIjpbInVI
-Il0sImJRIjpbInVIIl0sImNYIjpbInVIIl0sIkdtLkUiOiJ1SCIsImxELkUiOiJ1SCJ9LCJjZiI6eyJZ
-ayI6WyJxVSIsInFVIl0sIlowIjpbInFVIiwicVUiXX0sImk3Ijp7IllrIjpbInFVIiwicVUiXSwiWjAi
-OlsicVUiLCJxVSJdLCJZay5LIjoicVUiLCJZay5WIjoicVUifSwiU3kiOnsiWWsiOlsicVUiLCJxVSJd
-LCJaMCI6WyJxVSIsInFVIl0sIllrLksiOiJxVSIsIllrLlYiOiJxVSJ9LCJJNCI6eyJNYSI6WyJxVSJd
-LCJ4dSI6WyJxVSJdLCJiUSI6WyJxVSJdLCJjWCI6WyJxVSJdfSwiUk8iOnsicWgiOlsiMSJdfSwiZXUi
-OnsiUk8iOlsiMSJdLCJxaCI6WyIxIl19LCJ4QyI6eyJNTyI6WyIxIl19LCJKUSI6eyJrRiI6W119LCJ2
-RCI6eyJrRiI6W119LCJtNiI6eyJrRiI6W119LCJjdCI6eyJrRiI6W119LCJPdyI6eyJrRiI6W119LCJX
-OSI6eyJBbiI6WyIxIl19LCJkVyI6eyJ2NiI6W10sIkQwIjpbXX0sIm1rIjp7InkwIjpbXX0sIktvIjp7
-Im9uIjpbXX0sIkFzIjp7Ik1hIjpbInFVIl0sInh1IjpbInFVIl0sImJRIjpbInFVIl0sImNYIjpbInFV
-Il19LCJyNyI6eyJFNCI6W119LCJUeiI6eyJsRCI6WyIxIl0sInpNIjpbIjEiXSwiYlEiOlsiMSJdLCJF
-NCI6W10sImNYIjpbIjEiXSwibEQuRSI6IjEifSwiYkIiOnsiZDUiOltdLCJjdiI6W10sInVIIjpbXSwi
-RDAiOltdfSwiS2UiOnsiTWEiOlsicVUiXSwieHUiOlsicVUiXSwiYlEiOlsicVUiXSwiY1giOlsicVUi
-XX0sImQ1Ijp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJuNiI6eyJ6TSI6WyJJZiJdLCJiUSI6WyJJ
-ZiJdLCJBUyI6W10sImNYIjpbIklmIl19LCJYQSI6eyJrRiI6W119LCJPRiI6eyJmdiI6W119LCJydSI6
-eyJmdiI6W119LCJJViI6eyJmdiI6W119fScpKQpILkZGKHYudHlwZVVuaXZlcnNlLEpTT04ucGFyc2Uo
-J3siYlEiOjEsIncyIjoxLCJiMCI6MSwia1QiOjIsIm1XIjoxLCJMVSI6MSwiaWwiOjIsIlZqIjoxLCJu
-WSI6MSwiVEMiOjEsImNvIjoxfScpKQp2YXIgdT0oZnVuY3Rpb24gcnRpaSgpe3ZhciB0PUguTjAKcmV0
-dXJue2JxOnQoIkdoIiksbjp0KCJPSCIpLGNSOnQoIm5CIiksZDp0KCJBeiIpLGk6dCgiUVAiKSxnRjp0
-KCJQRDxHRCxAPiIpLGd3OnQoImJRPEA+IiksaDp0KCJjdiIpLFc6dCgiWFMiKSxCOnQoImVhIiksdTp0
-KCJEMCIpLGM4OnQoIlQ1IiksWjp0KCJFSCIpLGFROnQoImI4PGM4PiIpLGM6dCgiYjg8QD4iKSxyOnQo
-ImZKIiksSTp0KCJTZyIpLG86dCgidlEiKSxlaDp0KCJjWDx1SD4iKSxYOnQoImNYPHFVPiIpLFI6dCgi
-Y1g8QD4iKSxmQTp0KCJqZDxTZT4iKSxnaTp0KCJqZDxqOD4iKSxmaDp0KCJqZDxaWj4iKSxrOnQoImpk
-PGtGPiIpLHM6dCgiamQ8cVU+IiksaGg6dCgiamQ8eUQ+IiksYUo6dCgiamQ8d2I+Iiksdjp0KCJqZDxA
-PiIpLHQ6dCgiamQ8SWY+IiksZUg6dCgidm0iKSxnOnQoImM1IiksYVU6dCgiWGo8QD4iKSxhbTp0KCJU
-ejxAPiIpLGVvOnQoIk41PEdELEA+IiksaGI6dCgiRTQiKSxkejp0KCJoRiIpLGY0OnQoInpNPGo4PiIp
-LGE6dCgiek08cVU+Iiksajp0KCJ6TTxAPiIpLEw6dCgiek08SWY+IiksYV86dCgidTgiKSxTOnQoIlow
-PHFVLE1oPiIpLGY6dCgiWjA8cVUscVU+IiksYjp0KCJaMDxxVSxAPiIpLEc6dCgiWjA8QCxAPiIpLGR2
-OnQoImxKPHFVLHFVPiIpLGRvOnQoImxKPHFVLEA+IiksVjp0KCJPSyIpLGREOnQoInBGIiksYm06dCgi
-VjYiKSxBOnQoInVIIiksZTp0KCJrRiIpLFA6dCgiYzgiKSxLOnQoIk1oIiksY2E6dCgiTWgoTWgsTWgp
-IikscDp0KCJldyIpLE86dCgidG48bGY+IiksZnY6dCgid0wiKSxldzp0KCJiQiIpLEM6dCgieHU8cVU+
-IiksbDp0KCJHeiIpLE46dCgicVUiKSxkRzp0KCJxVShxVSkiKSxnNzp0KCJkNSIpLGZvOnQoIkdEIiks
-YVc6dCgieVkiKSx3OnQoIkFTIiksZ2M6dCgibjYiKSxhazp0KCJrZCIpLEQ6dCgiR2o8cVUscVU+Iiks
-Rjp0KCJpRCIpLGNjOnQoIlU1PHFVPiIpLGc0OnQoIks1IiksY2k6dCgidjYiKSxnMjp0KCJDbSIpLEU6
-dCgiWmY8Zko+IiksaDk6dCgiQ1EiKSxhYzp0KCJlNyIpLFE6dCgiZXU8T0s+IiksVDp0KCJ3ejxjdj4i
-KSx4OnQoIkZlPEAsQD4iKSxZOnQoInZzPGZKPiIpLF86dCgidnM8QD4iKSxmSjp0KCJ2czxJZj4iKSxj
-cjp0KCJKUSIpLEo6dCgiYm4iKSx5OnQoImEyIiksbTp0KCJhMihNaCkiKSxiQjp0KCJhMihxVSkiKSxn
-Ujp0KCJDUCIpLHo6dCgiQCIpLGZPOnQoIkAoKSIpLFU6dCgiQChlYSkiKSxiSTp0KCJAKE1oKSIpLGFn
-OnQoIkAoTWgsR3opIiksYlU6dCgiQCh4dTxxVT4pIiksZE86dCgiQChxVSkiKSxiODp0KCJAKEAsQCki
-KSxxOnQoIklmIiksYXc6dCgiMCYqIiksZGk6dCgibGYiKSxIOnQoIn4iKSxNOnQoIn4oKSIpLGFuOnQo
-In4oZXcpIiksZUE6dCgifihxVSxxVSkiKSxjQTp0KCJ+KHFVLEApIil9fSkoKTsoZnVuY3Rpb24gY29u
-c3RhbnRzKCl7dmFyIHQ9aHVua0hlbHBlcnMubWFrZUNvbnN0TGlzdApDLlJZPVcuUVAucHJvdG90eXBl
-CkMuQlo9Vy5WYi5wcm90b3R5cGUKQy5EdD1XLmZKLnByb3RvdHlwZQpDLk9rPUoudkIucHJvdG90eXBl
-CkMuTm09Si5qZC5wcm90b3R5cGUKQy5qbj1KLnVyLnByb3RvdHlwZQpDLkNEPUoucUkucHJvdG90eXBl
-CkMueEI9Si5Eci5wcm90b3R5cGUKQy5ERz1KLmM1LnByb3RvdHlwZQpDLkV4PVcudTgucHJvdG90eXBl
-CkMuTHQ9Vy5TTi5wcm90b3R5cGUKQy5aUT1KLmlDLnByb3RvdHlwZQpDLkllPVcuVGIucHJvdG90eXBl
-CkMudkI9Si5rZC5wcm90b3R5cGUKQy5vbD1XLks1LnByb3RvdHlwZQpDLnk4PW5ldyBQLlU4KCkKQy5o
-OT1uZXcgUC5DVigpCkMud2I9ZnVuY3Rpb24gZ2V0VGFnRmFsbGJhY2sobykgewogIHZhciBzID0gT2Jq
-ZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG8pOwogIHJldHVybiBzLnN1YnN0cmluZyg4LCBzLmxl
-bmd0aCAtIDEpOwp9CkMuTzQ9ZnVuY3Rpb24oKSB7CiAgdmFyIHRvU3RyaW5nRnVuY3Rpb24gPSBPYmpl
-Y3QucHJvdG90eXBlLnRvU3RyaW5nOwogIGZ1bmN0aW9uIGdldFRhZyhvKSB7CiAgICB2YXIgcyA9IHRv
-U3RyaW5nRnVuY3Rpb24uY2FsbChvKTsKICAgIHJldHVybiBzLnN1YnN0cmluZyg4LCBzLmxlbmd0aCAt
-IDEpOwogIH0KICBmdW5jdGlvbiBnZXRVbmtub3duVGFnKG9iamVjdCwgdGFnKSB7CiAgICBpZiAoL15I
-VE1MW0EtWl0uKkVsZW1lbnQkLy50ZXN0KHRhZykpIHsKICAgICAgdmFyIG5hbWUgPSB0b1N0cmluZ0Z1
-bmN0aW9uLmNhbGwob2JqZWN0KTsKICAgICAgaWYgKG5hbWUgPT0gIltvYmplY3QgT2JqZWN0XSIpIHJl
-dHVybiBudWxsOwogICAgICByZXR1cm4gIkhUTUxFbGVtZW50IjsKICAgIH0KICB9CiAgZnVuY3Rpb24g
-Z2V0VW5rbm93blRhZ0dlbmVyaWNCcm93c2VyKG9iamVjdCwgdGFnKSB7CiAgICBpZiAoc2VsZi5IVE1M
-RWxlbWVudCAmJiBvYmplY3QgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkgcmV0dXJuICJIVE1MRWxlbWVu
-dCI7CiAgICByZXR1cm4gZ2V0VW5rbm93blRhZyhvYmplY3QsIHRhZyk7CiAgfQogIGZ1bmN0aW9uIHBy
-b3RvdHlwZUZvclRhZyh0YWcpIHsKICAgIGlmICh0eXBlb2Ygd2luZG93ID09ICJ1bmRlZmluZWQiKSBy
-ZXR1cm4gbnVsbDsKICAgIGlmICh0eXBlb2Ygd2luZG93W3RhZ10gPT0gInVuZGVmaW5lZCIpIHJldHVy
-biBudWxsOwogICAgdmFyIGNvbnN0cnVjdG9yID0gd2luZG93W3RhZ107CiAgICBpZiAodHlwZW9mIGNv
-bnN0cnVjdG9yICE9ICJmdW5jdGlvbiIpIHJldHVybiBudWxsOwogICAgcmV0dXJuIGNvbnN0cnVjdG9y
-LnByb3RvdHlwZTsKICB9CiAgZnVuY3Rpb24gZGlzY3JpbWluYXRvcih0YWcpIHsgcmV0dXJuIG51bGw7
-IH0KICB2YXIgaXNCcm93c2VyID0gdHlwZW9mIG5hdmlnYXRvciA9PSAib2JqZWN0IjsKICByZXR1cm4g
-ewogICAgZ2V0VGFnOiBnZXRUYWcsCiAgICBnZXRVbmtub3duVGFnOiBpc0Jyb3dzZXIgPyBnZXRVbmtu
-b3duVGFnR2VuZXJpY0Jyb3dzZXIgOiBnZXRVbmtub3duVGFnLAogICAgcHJvdG90eXBlRm9yVGFnOiBw
-cm90b3R5cGVGb3JUYWcsCiAgICBkaXNjcmltaW5hdG9yOiBkaXNjcmltaW5hdG9yIH07Cn0KQy5kaz1m
-dW5jdGlvbihnZXRUYWdGYWxsYmFjaykgewogIHJldHVybiBmdW5jdGlvbihob29rcykgewogICAgaWYg
-KHR5cGVvZiBuYXZpZ2F0b3IgIT0gIm9iamVjdCIpIHJldHVybiBob29rczsKICAgIHZhciB1YSA9IG5h
-dmlnYXRvci51c2VyQWdlbnQ7CiAgICBpZiAodWEuaW5kZXhPZigiRHVtcFJlbmRlclRyZWUiKSA+PSAw
-KSByZXR1cm4gaG9va3M7CiAgICBpZiAodWEuaW5kZXhPZigiQ2hyb21lIikgPj0gMCkgewogICAgICBm
-dW5jdGlvbiBjb25maXJtKHApIHsKICAgICAgICByZXR1cm4gdHlwZW9mIHdpbmRvdyA9PSAib2JqZWN0
-IiAmJiB3aW5kb3dbcF0gJiYgd2luZG93W3BdLm5hbWUgPT0gcDsKICAgICAgfQogICAgICBpZiAoY29u
-ZmlybSgiV2luZG93IikgJiYgY29uZmlybSgiSFRNTEVsZW1lbnQiKSkgcmV0dXJuIGhvb2tzOwogICAg
-fQogICAgaG9va3MuZ2V0VGFnID0gZ2V0VGFnRmFsbGJhY2s7CiAgfTsKfQpDLllxPWZ1bmN0aW9uKGhv
-b2tzKSB7CiAgaWYgKHR5cGVvZiBkYXJ0RXhwZXJpbWVudGFsRml4dXBHZXRUYWcgIT0gImZ1bmN0aW9u
-IikgcmV0dXJuIGhvb2tzOwogIGhvb2tzLmdldFRhZyA9IGRhcnRFeHBlcmltZW50YWxGaXh1cEdldFRh
-Zyhob29rcy5nZXRUYWcpOwp9CkMuS1U9ZnVuY3Rpb24oaG9va3MpIHsKICB2YXIgZ2V0VGFnID0gaG9v
-a3MuZ2V0VGFnOwogIHZhciBwcm90b3R5cGVGb3JUYWcgPSBob29rcy5wcm90b3R5cGVGb3JUYWc7CiAg
-ZnVuY3Rpb24gZ2V0VGFnRml4ZWQobykgewogICAgdmFyIHRhZyA9IGdldFRhZyhvKTsKICAgIGlmICh0
-YWcgPT0gIkRvY3VtZW50IikgewogICAgICBpZiAoISFvLnhtbFZlcnNpb24pIHJldHVybiAiIURvY3Vt
-ZW50IjsKICAgICAgcmV0dXJuICIhSFRNTERvY3VtZW50IjsKICAgIH0KICAgIHJldHVybiB0YWc7CiAg
-fQogIGZ1bmN0aW9uIHByb3RvdHlwZUZvclRhZ0ZpeGVkKHRhZykgewogICAgaWYgKHRhZyA9PSAiRG9j
-dW1lbnQiKSByZXR1cm4gbnVsbDsKICAgIHJldHVybiBwcm90b3R5cGVGb3JUYWcodGFnKTsKICB9CiAg
-aG9va3MuZ2V0VGFnID0gZ2V0VGFnRml4ZWQ7CiAgaG9va3MucHJvdG90eXBlRm9yVGFnID0gcHJvdG90
-eXBlRm9yVGFnRml4ZWQ7Cn0KQy54aT1mdW5jdGlvbihob29rcykgewogIHZhciB1c2VyQWdlbnQgPSB0
-eXBlb2YgbmF2aWdhdG9yID09ICJvYmplY3QiID8gbmF2aWdhdG9yLnVzZXJBZ2VudCA6ICIiOwogIGlm
-ICh1c2VyQWdlbnQuaW5kZXhPZigiRmlyZWZveCIpID09IC0xKSByZXR1cm4gaG9va3M7CiAgdmFyIGdl
-dFRhZyA9IGhvb2tzLmdldFRhZzsKICB2YXIgcXVpY2tNYXAgPSB7CiAgICAiQmVmb3JlVW5sb2FkRXZl
-bnQiOiAiRXZlbnQiLAogICAgIkRhdGFUcmFuc2ZlciI6ICJDbGlwYm9hcmQiLAogICAgIkdlb0dlb2xv
-Y2F0aW9uIjogIkdlb2xvY2F0aW9uIiwKICAgICJMb2NhdGlvbiI6ICIhTG9jYXRpb24iLAogICAgIldv
-cmtlck1lc3NhZ2VFdmVudCI6ICJNZXNzYWdlRXZlbnQiLAogICAgIlhNTERvY3VtZW50IjogIiFEb2N1
-bWVudCJ9OwogIGZ1bmN0aW9uIGdldFRhZ0ZpcmVmb3gobykgewogICAgdmFyIHRhZyA9IGdldFRhZyhv
-KTsKICAgIHJldHVybiBxdWlja01hcFt0YWddIHx8IHRhZzsKICB9CiAgaG9va3MuZ2V0VGFnID0gZ2V0
-VGFnRmlyZWZveDsKfQpDLmk3PWZ1bmN0aW9uKGhvb2tzKSB7CiAgdmFyIHVzZXJBZ2VudCA9IHR5cGVv
-ZiBuYXZpZ2F0b3IgPT0gIm9iamVjdCIgPyBuYXZpZ2F0b3IudXNlckFnZW50IDogIiI7CiAgaWYgKHVz
-ZXJBZ2VudC5pbmRleE9mKCJUcmlkZW50LyIpID09IC0xKSByZXR1cm4gaG9va3M7CiAgdmFyIGdldFRh
-ZyA9IGhvb2tzLmdldFRhZzsKICB2YXIgcXVpY2tNYXAgPSB7CiAgICAiQmVmb3JlVW5sb2FkRXZlbnQi
-OiAiRXZlbnQiLAogICAgIkRhdGFUcmFuc2ZlciI6ICJDbGlwYm9hcmQiLAogICAgIkhUTUxEREVsZW1l
-bnQiOiAiSFRNTEVsZW1lbnQiLAogICAgIkhUTUxEVEVsZW1lbnQiOiAiSFRNTEVsZW1lbnQiLAogICAg
-IkhUTUxQaHJhc2VFbGVtZW50IjogIkhUTUxFbGVtZW50IiwKICAgICJQb3NpdGlvbiI6ICJHZW9wb3Np
-dGlvbiIKICB9OwogIGZ1bmN0aW9uIGdldFRhZ0lFKG8pIHsKICAgIHZhciB0YWcgPSBnZXRUYWcobyk7
-CiAgICB2YXIgbmV3VGFnID0gcXVpY2tNYXBbdGFnXTsKICAgIGlmIChuZXdUYWcpIHJldHVybiBuZXdU
-YWc7CiAgICBpZiAodGFnID09ICJPYmplY3QiKSB7CiAgICAgIGlmICh3aW5kb3cuRGF0YVZpZXcgJiYg
-KG8gaW5zdGFuY2VvZiB3aW5kb3cuRGF0YVZpZXcpKSByZXR1cm4gIkRhdGFWaWV3IjsKICAgIH0KICAg
-IHJldHVybiB0YWc7CiAgfQogIGZ1bmN0aW9uIHByb3RvdHlwZUZvclRhZ0lFKHRhZykgewogICAgdmFy
-IGNvbnN0cnVjdG9yID0gd2luZG93W3RhZ107CiAgICBpZiAoY29uc3RydWN0b3IgPT0gbnVsbCkgcmV0
-dXJuIG51bGw7CiAgICByZXR1cm4gY29uc3RydWN0b3IucHJvdG90eXBlOwogIH0KICBob29rcy5nZXRU
-YWcgPSBnZXRUYWdJRTsKICBob29rcy5wcm90b3R5cGVGb3JUYWcgPSBwcm90b3R5cGVGb3JUYWdJRTsK
-fQpDLmZRPWZ1bmN0aW9uKGhvb2tzKSB7IHJldHVybiBob29rczsgfQoKQy5DdD1uZXcgUC5ieSgpCkMu
-RXE9bmV3IFAuazUoKQpDLnhNPW5ldyBQLnU1KCkKQy5Raz1uZXcgUC5FMygpCkMuTlU9bmV3IFAuSmko
-KQpDLnBkPW5ldyBQLlpkKCkKQy5BMz1uZXcgUC5NeChudWxsKQpDLkdiPUguVk0odChbMTI3LDIwNDcs
-NjU1MzUsMTExNDExMV0pLHUudCkKQy5haz1ILlZNKHQoWzAsMCwzMjc3NiwzMzc5MiwxLDEwMjQwLDAs
-MF0pLHUudCkKQy5jbT1ILlZNKHQoWyIqOjpjbGFzcyIsIio6OmRpciIsIio6OmRyYWdnYWJsZSIsIio6
-OmhpZGRlbiIsIio6OmlkIiwiKjo6aW5lcnQiLCIqOjppdGVtcHJvcCIsIio6Oml0ZW1yZWYiLCIqOjpp
-dGVtc2NvcGUiLCIqOjpsYW5nIiwiKjo6c3BlbGxjaGVjayIsIio6OnRpdGxlIiwiKjo6dHJhbnNsYXRl
-IiwiQTo6YWNjZXNza2V5IiwiQTo6Y29vcmRzIiwiQTo6aHJlZmxhbmciLCJBOjpuYW1lIiwiQTo6c2hh
-cGUiLCJBOjp0YWJpbmRleCIsIkE6OnRhcmdldCIsIkE6OnR5cGUiLCJBUkVBOjphY2Nlc3NrZXkiLCJB
-UkVBOjphbHQiLCJBUkVBOjpjb29yZHMiLCJBUkVBOjpub2hyZWYiLCJBUkVBOjpzaGFwZSIsIkFSRUE6
-OnRhYmluZGV4IiwiQVJFQTo6dGFyZ2V0IiwiQVVESU86OmNvbnRyb2xzIiwiQVVESU86Omxvb3AiLCJB
-VURJTzo6bWVkaWFncm91cCIsIkFVRElPOjptdXRlZCIsIkFVRElPOjpwcmVsb2FkIiwiQkRPOjpkaXIi
-LCJCT0RZOjphbGluayIsIkJPRFk6OmJnY29sb3IiLCJCT0RZOjpsaW5rIiwiQk9EWTo6dGV4dCIsIkJP
-RFk6OnZsaW5rIiwiQlI6OmNsZWFyIiwiQlVUVE9OOjphY2Nlc3NrZXkiLCJCVVRUT046OmRpc2FibGVk
-IiwiQlVUVE9OOjpuYW1lIiwiQlVUVE9OOjp0YWJpbmRleCIsIkJVVFRPTjo6dHlwZSIsIkJVVFRPTjo6
-dmFsdWUiLCJDQU5WQVM6OmhlaWdodCIsIkNBTlZBUzo6d2lkdGgiLCJDQVBUSU9OOjphbGlnbiIsIkNP
-TDo6YWxpZ24iLCJDT0w6OmNoYXIiLCJDT0w6OmNoYXJvZmYiLCJDT0w6OnNwYW4iLCJDT0w6OnZhbGln
-biIsIkNPTDo6d2lkdGgiLCJDT0xHUk9VUDo6YWxpZ24iLCJDT0xHUk9VUDo6Y2hhciIsIkNPTEdST1VQ
-OjpjaGFyb2ZmIiwiQ09MR1JPVVA6OnNwYW4iLCJDT0xHUk9VUDo6dmFsaWduIiwiQ09MR1JPVVA6Ondp
-ZHRoIiwiQ09NTUFORDo6Y2hlY2tlZCIsIkNPTU1BTkQ6OmNvbW1hbmQiLCJDT01NQU5EOjpkaXNhYmxl
-ZCIsIkNPTU1BTkQ6OmxhYmVsIiwiQ09NTUFORDo6cmFkaW9ncm91cCIsIkNPTU1BTkQ6OnR5cGUiLCJE
-QVRBOjp2YWx1ZSIsIkRFTDo6ZGF0ZXRpbWUiLCJERVRBSUxTOjpvcGVuIiwiRElSOjpjb21wYWN0Iiwi
-RElWOjphbGlnbiIsIkRMOjpjb21wYWN0IiwiRklFTERTRVQ6OmRpc2FibGVkIiwiRk9OVDo6Y29sb3Ii
-LCJGT05UOjpmYWNlIiwiRk9OVDo6c2l6ZSIsIkZPUk06OmFjY2VwdCIsIkZPUk06OmF1dG9jb21wbGV0
-ZSIsIkZPUk06OmVuY3R5cGUiLCJGT1JNOjptZXRob2QiLCJGT1JNOjpuYW1lIiwiRk9STTo6bm92YWxp
-ZGF0ZSIsIkZPUk06OnRhcmdldCIsIkZSQU1FOjpuYW1lIiwiSDE6OmFsaWduIiwiSDI6OmFsaWduIiwi
-SDM6OmFsaWduIiwiSDQ6OmFsaWduIiwiSDU6OmFsaWduIiwiSDY6OmFsaWduIiwiSFI6OmFsaWduIiwi
-SFI6Om5vc2hhZGUiLCJIUjo6c2l6ZSIsIkhSOjp3aWR0aCIsIkhUTUw6OnZlcnNpb24iLCJJRlJBTUU6
-OmFsaWduIiwiSUZSQU1FOjpmcmFtZWJvcmRlciIsIklGUkFNRTo6aGVpZ2h0IiwiSUZSQU1FOjptYXJn
-aW5oZWlnaHQiLCJJRlJBTUU6Om1hcmdpbndpZHRoIiwiSUZSQU1FOjp3aWR0aCIsIklNRzo6YWxpZ24i
-LCJJTUc6OmFsdCIsIklNRzo6Ym9yZGVyIiwiSU1HOjpoZWlnaHQiLCJJTUc6OmhzcGFjZSIsIklNRzo6
-aXNtYXAiLCJJTUc6Om5hbWUiLCJJTUc6OnVzZW1hcCIsIklNRzo6dnNwYWNlIiwiSU1HOjp3aWR0aCIs
-IklOUFVUOjphY2NlcHQiLCJJTlBVVDo6YWNjZXNza2V5IiwiSU5QVVQ6OmFsaWduIiwiSU5QVVQ6OmFs
-dCIsIklOUFVUOjphdXRvY29tcGxldGUiLCJJTlBVVDo6YXV0b2ZvY3VzIiwiSU5QVVQ6OmNoZWNrZWQi
-LCJJTlBVVDo6ZGlzYWJsZWQiLCJJTlBVVDo6aW5wdXRtb2RlIiwiSU5QVVQ6OmlzbWFwIiwiSU5QVVQ6
-Omxpc3QiLCJJTlBVVDo6bWF4IiwiSU5QVVQ6Om1heGxlbmd0aCIsIklOUFVUOjptaW4iLCJJTlBVVDo6
-bXVsdGlwbGUiLCJJTlBVVDo6bmFtZSIsIklOUFVUOjpwbGFjZWhvbGRlciIsIklOUFVUOjpyZWFkb25s
-eSIsIklOUFVUOjpyZXF1aXJlZCIsIklOUFVUOjpzaXplIiwiSU5QVVQ6OnN0ZXAiLCJJTlBVVDo6dGFi
-aW5kZXgiLCJJTlBVVDo6dHlwZSIsIklOUFVUOjp1c2VtYXAiLCJJTlBVVDo6dmFsdWUiLCJJTlM6OmRh
-dGV0aW1lIiwiS0VZR0VOOjpkaXNhYmxlZCIsIktFWUdFTjo6a2V5dHlwZSIsIktFWUdFTjo6bmFtZSIs
-IkxBQkVMOjphY2Nlc3NrZXkiLCJMQUJFTDo6Zm9yIiwiTEVHRU5EOjphY2Nlc3NrZXkiLCJMRUdFTkQ6
-OmFsaWduIiwiTEk6OnR5cGUiLCJMSTo6dmFsdWUiLCJMSU5LOjpzaXplcyIsIk1BUDo6bmFtZSIsIk1F
-TlU6OmNvbXBhY3QiLCJNRU5VOjpsYWJlbCIsIk1FTlU6OnR5cGUiLCJNRVRFUjo6aGlnaCIsIk1FVEVS
-Ojpsb3ciLCJNRVRFUjo6bWF4IiwiTUVURVI6Om1pbiIsIk1FVEVSOjp2YWx1ZSIsIk9CSkVDVDo6dHlw
-ZW11c3RtYXRjaCIsIk9MOjpjb21wYWN0IiwiT0w6OnJldmVyc2VkIiwiT0w6OnN0YXJ0IiwiT0w6OnR5
-cGUiLCJPUFRHUk9VUDo6ZGlzYWJsZWQiLCJPUFRHUk9VUDo6bGFiZWwiLCJPUFRJT046OmRpc2FibGVk
-IiwiT1BUSU9OOjpsYWJlbCIsIk9QVElPTjo6c2VsZWN0ZWQiLCJPUFRJT046OnZhbHVlIiwiT1VUUFVU
-Ojpmb3IiLCJPVVRQVVQ6Om5hbWUiLCJQOjphbGlnbiIsIlBSRTo6d2lkdGgiLCJQUk9HUkVTUzo6bWF4
-IiwiUFJPR1JFU1M6Om1pbiIsIlBST0dSRVNTOjp2YWx1ZSIsIlNFTEVDVDo6YXV0b2NvbXBsZXRlIiwi
-U0VMRUNUOjpkaXNhYmxlZCIsIlNFTEVDVDo6bXVsdGlwbGUiLCJTRUxFQ1Q6Om5hbWUiLCJTRUxFQ1Q6
-OnJlcXVpcmVkIiwiU0VMRUNUOjpzaXplIiwiU0VMRUNUOjp0YWJpbmRleCIsIlNPVVJDRTo6dHlwZSIs
-IlRBQkxFOjphbGlnbiIsIlRBQkxFOjpiZ2NvbG9yIiwiVEFCTEU6OmJvcmRlciIsIlRBQkxFOjpjZWxs
-cGFkZGluZyIsIlRBQkxFOjpjZWxsc3BhY2luZyIsIlRBQkxFOjpmcmFtZSIsIlRBQkxFOjpydWxlcyIs
-IlRBQkxFOjpzdW1tYXJ5IiwiVEFCTEU6OndpZHRoIiwiVEJPRFk6OmFsaWduIiwiVEJPRFk6OmNoYXIi
-LCJUQk9EWTo6Y2hhcm9mZiIsIlRCT0RZOjp2YWxpZ24iLCJURDo6YWJiciIsIlREOjphbGlnbiIsIlRE
-OjpheGlzIiwiVEQ6OmJnY29sb3IiLCJURDo6Y2hhciIsIlREOjpjaGFyb2ZmIiwiVEQ6OmNvbHNwYW4i
-LCJURDo6aGVhZGVycyIsIlREOjpoZWlnaHQiLCJURDo6bm93cmFwIiwiVEQ6OnJvd3NwYW4iLCJURDo6
-c2NvcGUiLCJURDo6dmFsaWduIiwiVEQ6OndpZHRoIiwiVEVYVEFSRUE6OmFjY2Vzc2tleSIsIlRFWFRB
-UkVBOjphdXRvY29tcGxldGUiLCJURVhUQVJFQTo6Y29scyIsIlRFWFRBUkVBOjpkaXNhYmxlZCIsIlRF
-WFRBUkVBOjppbnB1dG1vZGUiLCJURVhUQVJFQTo6bmFtZSIsIlRFWFRBUkVBOjpwbGFjZWhvbGRlciIs
-IlRFWFRBUkVBOjpyZWFkb25seSIsIlRFWFRBUkVBOjpyZXF1aXJlZCIsIlRFWFRBUkVBOjpyb3dzIiwi
-VEVYVEFSRUE6OnRhYmluZGV4IiwiVEVYVEFSRUE6OndyYXAiLCJURk9PVDo6YWxpZ24iLCJURk9PVDo6
-Y2hhciIsIlRGT09UOjpjaGFyb2ZmIiwiVEZPT1Q6OnZhbGlnbiIsIlRIOjphYmJyIiwiVEg6OmFsaWdu
-IiwiVEg6OmF4aXMiLCJUSDo6Ymdjb2xvciIsIlRIOjpjaGFyIiwiVEg6OmNoYXJvZmYiLCJUSDo6Y29s
-c3BhbiIsIlRIOjpoZWFkZXJzIiwiVEg6OmhlaWdodCIsIlRIOjpub3dyYXAiLCJUSDo6cm93c3BhbiIs
-IlRIOjpzY29wZSIsIlRIOjp2YWxpZ24iLCJUSDo6d2lkdGgiLCJUSEVBRDo6YWxpZ24iLCJUSEVBRDo6
-Y2hhciIsIlRIRUFEOjpjaGFyb2ZmIiwiVEhFQUQ6OnZhbGlnbiIsIlRSOjphbGlnbiIsIlRSOjpiZ2Nv
-bG9yIiwiVFI6OmNoYXIiLCJUUjo6Y2hhcm9mZiIsIlRSOjp2YWxpZ24iLCJUUkFDSzo6ZGVmYXVsdCIs
-IlRSQUNLOjpraW5kIiwiVFJBQ0s6OmxhYmVsIiwiVFJBQ0s6OnNyY2xhbmciLCJVTDo6Y29tcGFjdCIs
-IlVMOjp0eXBlIiwiVklERU86OmNvbnRyb2xzIiwiVklERU86OmhlaWdodCIsIlZJREVPOjpsb29wIiwi
-VklERU86Om1lZGlhZ3JvdXAiLCJWSURFTzo6bXV0ZWQiLCJWSURFTzo6cHJlbG9hZCIsIlZJREVPOjp3
-aWR0aCJdKSx1LnMpCkMuVkM9SC5WTSh0KFswLDAsNjU0OTAsNDUwNTUsNjU1MzUsMzQ4MTUsNjU1MzQs
-MTg0MzFdKSx1LnQpCkMubUs9SC5WTSh0KFswLDAsMjY2MjQsMTAyMyw2NTUzNCwyMDQ3LDY1NTM0LDIw
-NDddKSx1LnQpCkMuU3E9SC5WTSh0KFsiSEVBRCIsIkFSRUEiLCJCQVNFIiwiQkFTRUZPTlQiLCJCUiIs
-IkNPTCIsIkNPTEdST1VQIiwiRU1CRUQiLCJGUkFNRSIsIkZSQU1FU0VUIiwiSFIiLCJJTUFHRSIsIklN
-RyIsIklOUFVUIiwiSVNJTkRFWCIsIkxJTksiLCJNRVRBIiwiUEFSQU0iLCJTT1VSQ0UiLCJTVFlMRSIs
-IlRJVExFIiwiV0JSIl0pLHUucykKQy54RD1ILlZNKHQoW10pLHUucykKQy5kbj1ILlZNKHQoW10pLHUu
-dikKQy50bz1ILlZNKHQoWzAsMCwzMjcyMiwxMjI4Nyw2NTUzNCwzNDgxNSw2NTUzNCwxODQzMV0pLHUu
-dCkKQy5GMz1ILlZNKHQoWzAsMCwyNDU3NiwxMDIzLDY1NTM0LDM0ODE1LDY1NTM0LDE4NDMxXSksdS50
-KQpDLmVhPUguVk0odChbMCwwLDMyNzU0LDExMjYzLDY1NTM0LDM0ODE1LDY1NTM0LDE4NDMxXSksdS50
-KQpDLlpKPUguVk0odChbMCwwLDMyNzIyLDEyMjg3LDY1NTM1LDM0ODE1LDY1NTM0LDE4NDMxXSksdS50
-KQpDLldkPUguVk0odChbMCwwLDY1NDkwLDEyMjg3LDY1NTM1LDM0ODE1LDY1NTM0LDE4NDMxXSksdS50
-KQpDLlF4PUguVk0odChbImJpbmQiLCJpZiIsInJlZiIsInJlcGVhdCIsInN5bnRheCJdKSx1LnMpCkMu
-Qkk9SC5WTSh0KFsiQTo6aHJlZiIsIkFSRUE6OmhyZWYiLCJCTE9DS1FVT1RFOjpjaXRlIiwiQk9EWTo6
-YmFja2dyb3VuZCIsIkNPTU1BTkQ6Omljb24iLCJERUw6OmNpdGUiLCJGT1JNOjphY3Rpb24iLCJJTUc6
-OnNyYyIsIklOUFVUOjpzcmMiLCJJTlM6OmNpdGUiLCJROjpjaXRlIiwiVklERU86OnBvc3RlciJdKSx1
-LnMpCkMuQ009bmV3IEguTFAoMCx7fSxDLnhELEguTjAoIkxQPHFVLHpNPGo4Pj4iKSkKQy5XTz1uZXcg
-SC5MUCgwLHt9LEMueEQsSC5OMCgiTFA8cVUscVU+IikpCkMuaFU9SC5WTSh0KFtdKSxILk4wKCJqZDxH
-RD4iKSkKQy5EeD1uZXcgSC5MUCgwLHt9LEMuaFUsSC5OMCgiTFA8R0QsQD4iKSkKQy5ZMj1uZXcgTC5P
-OSgiTmF2aWdhdGlvblRyZWVOb2RlVHlwZS5kaXJlY3RvcnkiKQpDLnJmPW5ldyBMLk85KCJOYXZpZ2F0
-aW9uVHJlZU5vZGVUeXBlLmZpbGUiKQpDLlRlPW5ldyBILnd2KCJjYWxsIikKQy53UT1uZXcgUC5GeShu
-dWxsLDIpfSkoKTsoZnVuY3Rpb24gc3RhdGljRmllbGRzKCl7JC55aj0wCiQubUo9bnVsbAokLlA0PW51
-bGwKJC55PW51bGwKJC51PW51bGwKJC54Nz1udWxsCiQuaj1udWxsCiQudj1udWxsCiQuSz1udWxsCiQu
-UzY9bnVsbAokLms4PW51bGwKJC5tZz1udWxsCiQuVUQ9ITEKJC5YMz1DLk5VCiQueGc9W10KJC54bz1u
-dWxsCiQuQk89bnVsbAokLmx0PW51bGwKJC5FVT1udWxsCiQub3I9UC5GbCh1Lk4sdS5aKQokLkk2PW51
-bGwKJC5GZj1udWxsfSkoKTsoZnVuY3Rpb24gbGF6eUluaXRpYWxpemVycygpe3ZhciB0PWh1bmtIZWxw
-ZXJzLmxhenkKdCgkLCJmYSIsIndRIixmdW5jdGlvbigpe3JldHVybiBILllnKCJfJGRhcnRfZGFydENs
-b3N1cmUiKX0pCnQoJCwiWTIiLCJBIixmdW5jdGlvbigpe3JldHVybiBILllnKCJfJGRhcnRfanMiKX0p
-CnQoJCwiVTIiLCJTbiIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShILlM3KHsKdG9TdHJpbmc6ZnVuY3Rp
-b24oKXtyZXR1cm4iJHJlY2VpdmVyJCJ9fSkpfSkKdCgkLCJ4cSIsImxxIixmdW5jdGlvbigpe3JldHVy
-biBILmNNKEguUzcoeyRtZXRob2QkOm51bGwsCnRvU3RyaW5nOmZ1bmN0aW9uKCl7cmV0dXJuIiRyZWNl
-aXZlciQifX0pKX0pCnQoJCwiUjEiLCJOOSIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShILlM3KG51bGwp
-KX0pCnQoJCwiZk4iLCJpSSIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShmdW5jdGlvbigpe3ZhciAkYXJn
-dW1lbnRzRXhwciQ9JyRhcmd1bWVudHMkJwp0cnl7bnVsbC4kbWV0aG9kJCgkYXJndW1lbnRzRXhwciQp
-fWNhdGNoKHMpe3JldHVybiBzLm1lc3NhZ2V9fSgpKX0pCnQoJCwicWkiLCJVTiIsZnVuY3Rpb24oKXty
-ZXR1cm4gSC5jTShILlM3KHZvaWQgMCkpfSkKdCgkLCJyWiIsIlpoIixmdW5jdGlvbigpe3JldHVybiBI
-LmNNKGZ1bmN0aW9uKCl7dmFyICRhcmd1bWVudHNFeHByJD0nJGFyZ3VtZW50cyQnCnRyeXsodm9pZCAw
-KS4kbWV0aG9kJCgkYXJndW1lbnRzRXhwciQpfWNhdGNoKHMpe3JldHVybiBzLm1lc3NhZ2V9fSgpKX0p
-CnQoJCwia3EiLCJyTiIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShILk1qKG51bGwpKX0pCnQoJCwidHQi
-LCJjMyIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShmdW5jdGlvbigpe3RyeXtudWxsLiRtZXRob2QkfWNh
-dGNoKHMpe3JldHVybiBzLm1lc3NhZ2V9fSgpKX0pCnQoJCwiZHQiLCJISyIsZnVuY3Rpb24oKXtyZXR1
-cm4gSC5jTShILk1qKHZvaWQgMCkpfSkKdCgkLCJBNyIsInIxIixmdW5jdGlvbigpe3JldHVybiBILmNN
-KGZ1bmN0aW9uKCl7dHJ5eyh2b2lkIDApLiRtZXRob2QkfWNhdGNoKHMpe3JldHVybiBzLm1lc3NhZ2V9
-fSgpKX0pCnQoJCwiV2MiLCJ1dCIsZnVuY3Rpb24oKXtyZXR1cm4gUC5PaigpfSkKdCgkLCJraCIsInRM
-IixmdW5jdGlvbigpe3JldHVybiBuZXcgUC5wZygpLiQwKCl9KQp0KCQsImJ0IiwiVjciLGZ1bmN0aW9u
-KCl7cmV0dXJuIG5ldyBJbnQ4QXJyYXkoSC5YRihILlZNKFstMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwt
-MiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwt
-MiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMSwtMiwtMiwtMiwtMiwtMiw2MiwtMiw2MiwtMiw2Myw1
-Miw1Myw1NCw1NSw1Niw1Nyw1OCw1OSw2MCw2MSwtMiwtMiwtMiwtMSwtMiwtMiwtMiwwLDEsMiwzLDQs
-NSw2LDcsOCw5LDEwLDExLDEyLDEzLDE0LDE1LDE2LDE3LDE4LDE5LDIwLDIxLDIyLDIzLDI0LDI1LC0y
-LC0yLC0yLC0yLDYzLC0yLDI2LDI3LDI4LDI5LDMwLDMxLDMyLDMzLDM0LDM1LDM2LDM3LDM4LDM5LDQw
-LDQxLDQyLDQzLDQ0LDQ1LDQ2LDQ3LDQ4LDQ5LDUwLDUxLC0yLC0yLC0yLC0yLC0yXSx1LnQpKSl9KQp0
-KCQsIk01IiwiT3giLGZ1bmN0aW9uKCl7cmV0dXJuIHR5cGVvZiBwcm9jZXNzIT0idW5kZWZpbmVkIiYm
-T2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHByb2Nlc3MpPT0iW29iamVjdCBwcm9jZXNzXSIm
-JnByb2Nlc3MucGxhdGZvcm09PSJ3aW4zMiJ9KQp0KCQsIm1mIiwiejQiLGZ1bmN0aW9uKCl7cmV0dXJu
-IFAubnUoIl5bXFwtXFwuMC05QS1aX2Eten5dKiQiKX0pCnQoJCwiSkciLCJ2WiIsZnVuY3Rpb24oKXty
-ZXR1cm4gUC5LTigpfSkKdCgkLCJTQyIsIkFOIixmdW5jdGlvbigpe3JldHVybiBQLnRNKFsiQSIsIkFC
-QlIiLCJBQ1JPTllNIiwiQUREUkVTUyIsIkFSRUEiLCJBUlRJQ0xFIiwiQVNJREUiLCJBVURJTyIsIkIi
-LCJCREkiLCJCRE8iLCJCSUciLCJCTE9DS1FVT1RFIiwiQlIiLCJCVVRUT04iLCJDQU5WQVMiLCJDQVBU
-SU9OIiwiQ0VOVEVSIiwiQ0lURSIsIkNPREUiLCJDT0wiLCJDT0xHUk9VUCIsIkNPTU1BTkQiLCJEQVRB
-IiwiREFUQUxJU1QiLCJERCIsIkRFTCIsIkRFVEFJTFMiLCJERk4iLCJESVIiLCJESVYiLCJETCIsIkRU
-IiwiRU0iLCJGSUVMRFNFVCIsIkZJR0NBUFRJT04iLCJGSUdVUkUiLCJGT05UIiwiRk9PVEVSIiwiRk9S
-TSIsIkgxIiwiSDIiLCJIMyIsIkg0IiwiSDUiLCJINiIsIkhFQURFUiIsIkhHUk9VUCIsIkhSIiwiSSIs
-IklGUkFNRSIsIklNRyIsIklOUFVUIiwiSU5TIiwiS0JEIiwiTEFCRUwiLCJMRUdFTkQiLCJMSSIsIk1B
-UCIsIk1BUksiLCJNRU5VIiwiTUVURVIiLCJOQVYiLCJOT0JSIiwiT0wiLCJPUFRHUk9VUCIsIk9QVElP
-TiIsIk9VVFBVVCIsIlAiLCJQUkUiLCJQUk9HUkVTUyIsIlEiLCJTIiwiU0FNUCIsIlNFQ1RJT04iLCJT
-RUxFQ1QiLCJTTUFMTCIsIlNPVVJDRSIsIlNQQU4iLCJTVFJJS0UiLCJTVFJPTkciLCJTVUIiLCJTVU1N
-QVJZIiwiU1VQIiwiVEFCTEUiLCJUQk9EWSIsIlREIiwiVEVYVEFSRUEiLCJURk9PVCIsIlRIIiwiVEhF
-QUQiLCJUSU1FIiwiVFIiLCJUUkFDSyIsIlRUIiwiVSIsIlVMIiwiVkFSIiwiVklERU8iLCJXQlIiXSx1
-Lk4pfSkKdCgkLCJYNCIsImhHIixmdW5jdGlvbigpe3JldHVybiBQLm51KCJeXFxTKyQiKX0pCnQoJCwi
-d08iLCJvdyIsZnVuY3Rpb24oKXtyZXR1cm4gUC5ORChzZWxmKX0pCnQoJCwia3QiLCJDciIsZnVuY3Rp
-b24oKXtyZXR1cm4gSC5ZZygiXyRkYXJ0X2RhcnRPYmplY3QiKX0pCnQoJCwiZksiLCJrSSIsZnVuY3Rp
-b24oKXtyZXR1cm4gZnVuY3Rpb24gRGFydE9iamVjdChhKXt0aGlzLm89YX19KQp0KCQsInF0IiwiekIi
-LGZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBULm1RKCl9KQp0KCQsIk9sIiwiVUUiLGZ1bmN0aW9uKCl7cmV0
-dXJuIFAuaEsoQy5vbC5nbVcoVy54MygpKS5ocmVmKS5naFkoKS5xKDAsImF1dGhUb2tlbiIpfSkKdCgk
-LCJoVCIsInlQIixmdW5jdGlvbigpe3JldHVybiBXLlpyKCkucXVlcnlTZWxlY3RvcigiLmVkaXQtbGlz
-dCAucGFuZWwtY29udGVudCIpfSkKdCgkLCJXNiIsImhMIixmdW5jdGlvbigpe3JldHVybiBXLlpyKCku
-cXVlcnlTZWxlY3RvcigiLmVkaXQtcGFuZWwgLnBhbmVsLWNvbnRlbnQiKX0pCnQoJCwiVFIiLCJEVyIs
-ZnVuY3Rpb24oKXtyZXR1cm4gVy5acigpLnF1ZXJ5U2VsZWN0b3IoImZvb3RlciIpfSkKdCgkLCJFWSIs
-ImZpIixmdW5jdGlvbigpe3JldHVybiBXLlpyKCkucXVlcnlTZWxlY3RvcigiaGVhZGVyIil9KQp0KCQs
-ImF2IiwiRDkiLGZ1bmN0aW9uKCl7cmV0dXJuIFcuWnIoKS5xdWVyeVNlbGVjdG9yKCIjdW5pdC1uYW1l
-Iil9KQp0KCQsImZlIiwiS0ciLGZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBMLlhBKCl9KQp0KCQsImVvIiwi
-blUiLGZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBNLmxJKCQuSGsoKSl9KQp0KCQsInlyIiwiYkQiLGZ1bmN0
-aW9uKCl7cmV0dXJuIG5ldyBFLk9GKFAubnUoIi8iKSxQLm51KCJbXi9dJCIpLFAubnUoIl4vIikpfSkK
-dCgkLCJNayIsIktrIixmdW5jdGlvbigpe3JldHVybiBuZXcgTC5JVihQLm51KCJbL1xcXFxdIiksUC5u
-dSgiW14vXFxcXF0kIiksUC5udSgiXihcXFxcXFxcXFteXFxcXF0rXFxcXFteXFxcXC9dK3xbYS16QS1a
-XTpbL1xcXFxdKSIpLFAubnUoIl5bL1xcXFxdKD8hWy9cXFxcXSkiKSl9KQp0KCQsImFrIiwiRWIiLGZ1
-bmN0aW9uKCl7cmV0dXJuIG5ldyBGLnJ1KFAubnUoIi8iKSxQLm51KCIoXlthLXpBLVpdWy0rLmEtekEt
-WlxcZF0qOi8vfFteL10pJCIpLFAubnUoIlthLXpBLVpdWy0rLmEtekEtWlxcZF0qOi8vW14vXSoiKSxQ
-Lm51KCJeLyIpKX0pCnQoJCwibHMiLCJIayIsZnVuY3Rpb24oKXtyZXR1cm4gTy5SaCgpfSl9KSgpOyhm
-dW5jdGlvbiBuYXRpdmVTdXBwb3J0KCl7IWZ1bmN0aW9uKCl7dmFyIHQ9ZnVuY3Rpb24oYSl7dmFyIG49
-e30KblthXT0xCnJldHVybiBPYmplY3Qua2V5cyhodW5rSGVscGVycy5jb252ZXJ0VG9GYXN0T2JqZWN0
-KG4pKVswXX0Kdi5nZXRJc29sYXRlVGFnPWZ1bmN0aW9uKGEpe3JldHVybiB0KCJfX19kYXJ0XyIrYSt2
-Lmlzb2xhdGVUYWcpfQp2YXIgcz0iX19fZGFydF9pc29sYXRlX3RhZ3NfIgp2YXIgcj1PYmplY3Rbc118
-fChPYmplY3Rbc109T2JqZWN0LmNyZWF0ZShudWxsKSkKdmFyIHE9Il9aeFl4WCIKZm9yKHZhciBwPTA7
-O3ArKyl7dmFyIG89dChxKyJfIitwKyJfIikKaWYoIShvIGluIHIpKXtyW29dPTEKdi5pc29sYXRlVGFn
-PW8KYnJlYWt9fXYuZGlzcGF0Y2hQcm9wZXJ0eU5hbWU9di5nZXRJc29sYXRlVGFnKCJkaXNwYXRjaF9y
-ZWNvcmQiKX0oKQpodW5rSGVscGVycy5zZXRPclVwZGF0ZUludGVyY2VwdG9yc0J5VGFnKHtET01FcnJv
-cjpKLnZCLERPTUltcGxlbWVudGF0aW9uOkoudkIsTWVkaWFFcnJvcjpKLnZCLE5hdmlnYXRvcjpKLnZC
-LE5hdmlnYXRvckNvbmN1cnJlbnRIYXJkd2FyZTpKLnZCLE5hdmlnYXRvclVzZXJNZWRpYUVycm9yOkou
-dkIsT3ZlcmNvbnN0cmFpbmVkRXJyb3I6Si52QixQb3NpdGlvbkVycm9yOkoudkIsUmFuZ2U6Si52QixT
-UUxFcnJvcjpKLnZCLERhdGFWaWV3OkgucEYsQXJyYXlCdWZmZXJWaWV3OkgucEYsRmxvYXQzMkFycmF5
-OkguRGcsRmxvYXQ2NEFycmF5OkguRGcsSW50MTZBcnJheTpILnhqLEludDMyQXJyYXk6SC5kRSxJbnQ4
-QXJyYXk6SC5aQSxVaW50MTZBcnJheTpILndmLFVpbnQzMkFycmF5OkguUHEsVWludDhDbGFtcGVkQXJy
-YXk6SC5lRSxDYW52YXNQaXhlbEFycmF5OkguZUUsVWludDhBcnJheTpILlY2LEhUTUxBdWRpb0VsZW1l
-bnQ6Vy5xRSxIVE1MQlJFbGVtZW50OlcucUUsSFRNTEJ1dHRvbkVsZW1lbnQ6Vy5xRSxIVE1MQ2FudmFz
-RWxlbWVudDpXLnFFLEhUTUxDb250ZW50RWxlbWVudDpXLnFFLEhUTUxETGlzdEVsZW1lbnQ6Vy5xRSxI
-VE1MRGF0YUVsZW1lbnQ6Vy5xRSxIVE1MRGF0YUxpc3RFbGVtZW50OlcucUUsSFRNTERldGFpbHNFbGVt
-ZW50OlcucUUsSFRNTERpYWxvZ0VsZW1lbnQ6Vy5xRSxIVE1MRGl2RWxlbWVudDpXLnFFLEhUTUxFbWJl
-ZEVsZW1lbnQ6Vy5xRSxIVE1MRmllbGRTZXRFbGVtZW50OlcucUUsSFRNTEhSRWxlbWVudDpXLnFFLEhU
-TUxIZWFkRWxlbWVudDpXLnFFLEhUTUxIZWFkaW5nRWxlbWVudDpXLnFFLEhUTUxIdG1sRWxlbWVudDpX
-LnFFLEhUTUxJRnJhbWVFbGVtZW50OlcucUUsSFRNTEltYWdlRWxlbWVudDpXLnFFLEhUTUxJbnB1dEVs
-ZW1lbnQ6Vy5xRSxIVE1MTElFbGVtZW50OlcucUUsSFRNTExhYmVsRWxlbWVudDpXLnFFLEhUTUxMZWdl
-bmRFbGVtZW50OlcucUUsSFRNTExpbmtFbGVtZW50OlcucUUsSFRNTE1hcEVsZW1lbnQ6Vy5xRSxIVE1M
-TWVkaWFFbGVtZW50OlcucUUsSFRNTE1lbnVFbGVtZW50OlcucUUsSFRNTE1ldGFFbGVtZW50OlcucUUs
-SFRNTE1ldGVyRWxlbWVudDpXLnFFLEhUTUxNb2RFbGVtZW50OlcucUUsSFRNTE9MaXN0RWxlbWVudDpX
-LnFFLEhUTUxPYmplY3RFbGVtZW50OlcucUUsSFRNTE9wdEdyb3VwRWxlbWVudDpXLnFFLEhUTUxPcHRp
-b25FbGVtZW50OlcucUUsSFRNTE91dHB1dEVsZW1lbnQ6Vy5xRSxIVE1MUGFyYW1FbGVtZW50OlcucUUs
-SFRNTFBpY3R1cmVFbGVtZW50OlcucUUsSFRNTFByZUVsZW1lbnQ6Vy5xRSxIVE1MUHJvZ3Jlc3NFbGVt
-ZW50OlcucUUsSFRNTFF1b3RlRWxlbWVudDpXLnFFLEhUTUxTY3JpcHRFbGVtZW50OlcucUUsSFRNTFNo
-YWRvd0VsZW1lbnQ6Vy5xRSxIVE1MU2xvdEVsZW1lbnQ6Vy5xRSxIVE1MU291cmNlRWxlbWVudDpXLnFF
-LEhUTUxTcGFuRWxlbWVudDpXLnFFLEhUTUxTdHlsZUVsZW1lbnQ6Vy5xRSxIVE1MVGFibGVDYXB0aW9u
-RWxlbWVudDpXLnFFLEhUTUxUYWJsZUNlbGxFbGVtZW50OlcucUUsSFRNTFRhYmxlRGF0YUNlbGxFbGVt
-ZW50OlcucUUsSFRNTFRhYmxlSGVhZGVyQ2VsbEVsZW1lbnQ6Vy5xRSxIVE1MVGFibGVDb2xFbGVtZW50
-OlcucUUsSFRNTFRleHRBcmVhRWxlbWVudDpXLnFFLEhUTUxUaW1lRWxlbWVudDpXLnFFLEhUTUxUaXRs
-ZUVsZW1lbnQ6Vy5xRSxIVE1MVHJhY2tFbGVtZW50OlcucUUsSFRNTFVMaXN0RWxlbWVudDpXLnFFLEhU
-TUxVbmtub3duRWxlbWVudDpXLnFFLEhUTUxWaWRlb0VsZW1lbnQ6Vy5xRSxIVE1MRGlyZWN0b3J5RWxl
-bWVudDpXLnFFLEhUTUxGb250RWxlbWVudDpXLnFFLEhUTUxGcmFtZUVsZW1lbnQ6Vy5xRSxIVE1MRnJh
-bWVTZXRFbGVtZW50OlcucUUsSFRNTE1hcnF1ZWVFbGVtZW50OlcucUUsSFRNTEVsZW1lbnQ6Vy5xRSxI
-VE1MQW5jaG9yRWxlbWVudDpXLkdoLEhUTUxBcmVhRWxlbWVudDpXLmZZLEhUTUxCYXNlRWxlbWVudDpX
-Lm5CLEJsb2I6Vy5BeixIVE1MQm9keUVsZW1lbnQ6Vy5RUCxDREFUQVNlY3Rpb246Vy5ueCxDaGFyYWN0
-ZXJEYXRhOlcubngsQ29tbWVudDpXLm54LFByb2Nlc3NpbmdJbnN0cnVjdGlvbjpXLm54LFRleHQ6Vy5u
-eCxDU1NTdHlsZURlY2xhcmF0aW9uOlcub0osTVNTdHlsZUNTU1Byb3BlcnRpZXM6Vy5vSixDU1MyUHJv
-cGVydGllczpXLm9KLFhNTERvY3VtZW50OlcuUUYsRG9jdW1lbnQ6Vy5RRixET01FeGNlcHRpb246Vy5O
-aCxET01SZWN0UmVhZE9ubHk6Vy5JQixET01Ub2tlbkxpc3Q6Vy5uNyxFbGVtZW50OlcuY3YsQWJvcnRQ
-YXltZW50RXZlbnQ6Vy5lYSxBbmltYXRpb25FdmVudDpXLmVhLEFuaW1hdGlvblBsYXliYWNrRXZlbnQ6
-Vy5lYSxBcHBsaWNhdGlvbkNhY2hlRXJyb3JFdmVudDpXLmVhLEJhY2tncm91bmRGZXRjaENsaWNrRXZl
-bnQ6Vy5lYSxCYWNrZ3JvdW5kRmV0Y2hFdmVudDpXLmVhLEJhY2tncm91bmRGZXRjaEZhaWxFdmVudDpX
-LmVhLEJhY2tncm91bmRGZXRjaGVkRXZlbnQ6Vy5lYSxCZWZvcmVJbnN0YWxsUHJvbXB0RXZlbnQ6Vy5l
-YSxCZWZvcmVVbmxvYWRFdmVudDpXLmVhLEJsb2JFdmVudDpXLmVhLENhbk1ha2VQYXltZW50RXZlbnQ6
-Vy5lYSxDbGlwYm9hcmRFdmVudDpXLmVhLENsb3NlRXZlbnQ6Vy5lYSxDdXN0b21FdmVudDpXLmVhLERl
-dmljZU1vdGlvbkV2ZW50OlcuZWEsRGV2aWNlT3JpZW50YXRpb25FdmVudDpXLmVhLEVycm9yRXZlbnQ6
-Vy5lYSxFeHRlbmRhYmxlRXZlbnQ6Vy5lYSxFeHRlbmRhYmxlTWVzc2FnZUV2ZW50OlcuZWEsRmV0Y2hF
-dmVudDpXLmVhLEZvbnRGYWNlU2V0TG9hZEV2ZW50OlcuZWEsRm9yZWlnbkZldGNoRXZlbnQ6Vy5lYSxH
-YW1lcGFkRXZlbnQ6Vy5lYSxIYXNoQ2hhbmdlRXZlbnQ6Vy5lYSxJbnN0YWxsRXZlbnQ6Vy5lYSxNZWRp
-YUVuY3J5cHRlZEV2ZW50OlcuZWEsTWVkaWFLZXlNZXNzYWdlRXZlbnQ6Vy5lYSxNZWRpYVF1ZXJ5TGlz
-dEV2ZW50OlcuZWEsTWVkaWFTdHJlYW1FdmVudDpXLmVhLE1lZGlhU3RyZWFtVHJhY2tFdmVudDpXLmVh
-LE1lc3NhZ2VFdmVudDpXLmVhLE1JRElDb25uZWN0aW9uRXZlbnQ6Vy5lYSxNSURJTWVzc2FnZUV2ZW50
-OlcuZWEsTXV0YXRpb25FdmVudDpXLmVhLE5vdGlmaWNhdGlvbkV2ZW50OlcuZWEsUGFnZVRyYW5zaXRp
-b25FdmVudDpXLmVhLFBheW1lbnRSZXF1ZXN0RXZlbnQ6Vy5lYSxQYXltZW50UmVxdWVzdFVwZGF0ZUV2
-ZW50OlcuZWEsUG9wU3RhdGVFdmVudDpXLmVhLFByZXNlbnRhdGlvbkNvbm5lY3Rpb25BdmFpbGFibGVF
-dmVudDpXLmVhLFByZXNlbnRhdGlvbkNvbm5lY3Rpb25DbG9zZUV2ZW50OlcuZWEsUHJvbWlzZVJlamVj
-dGlvbkV2ZW50OlcuZWEsUHVzaEV2ZW50OlcuZWEsUlRDRGF0YUNoYW5uZWxFdmVudDpXLmVhLFJUQ0RU
-TUZUb25lQ2hhbmdlRXZlbnQ6Vy5lYSxSVENQZWVyQ29ubmVjdGlvbkljZUV2ZW50OlcuZWEsUlRDVHJh
-Y2tFdmVudDpXLmVhLFNlY3VyaXR5UG9saWN5VmlvbGF0aW9uRXZlbnQ6Vy5lYSxTZW5zb3JFcnJvckV2
-ZW50OlcuZWEsU3BlZWNoUmVjb2duaXRpb25FcnJvcjpXLmVhLFNwZWVjaFJlY29nbml0aW9uRXZlbnQ6
-Vy5lYSxTcGVlY2hTeW50aGVzaXNFdmVudDpXLmVhLFN0b3JhZ2VFdmVudDpXLmVhLFN5bmNFdmVudDpX
-LmVhLFRyYWNrRXZlbnQ6Vy5lYSxUcmFuc2l0aW9uRXZlbnQ6Vy5lYSxXZWJLaXRUcmFuc2l0aW9uRXZl
-bnQ6Vy5lYSxWUkRldmljZUV2ZW50OlcuZWEsVlJEaXNwbGF5RXZlbnQ6Vy5lYSxWUlNlc3Npb25FdmVu
-dDpXLmVhLE1vam9JbnRlcmZhY2VSZXF1ZXN0RXZlbnQ6Vy5lYSxVU0JDb25uZWN0aW9uRXZlbnQ6Vy5l
-YSxJREJWZXJzaW9uQ2hhbmdlRXZlbnQ6Vy5lYSxBdWRpb1Byb2Nlc3NpbmdFdmVudDpXLmVhLE9mZmxp
-bmVBdWRpb0NvbXBsZXRpb25FdmVudDpXLmVhLFdlYkdMQ29udGV4dEV2ZW50OlcuZWEsRXZlbnQ6Vy5l
-YSxJbnB1dEV2ZW50OlcuZWEsRXZlbnRUYXJnZXQ6Vy5EMCxGaWxlOlcuVDUsSFRNTEZvcm1FbGVtZW50
-OlcuaDQsSGlzdG9yeTpXLmJyLEhUTUxEb2N1bWVudDpXLlZiLFhNTEh0dHBSZXF1ZXN0OlcuZkosWE1M
-SHR0cFJlcXVlc3RFdmVudFRhcmdldDpXLndhLEltYWdlRGF0YTpXLlNnLExvY2F0aW9uOlcudTgsTW91
-c2VFdmVudDpXLk9LLERyYWdFdmVudDpXLk9LLFBvaW50ZXJFdmVudDpXLk9LLFdoZWVsRXZlbnQ6Vy5P
-SyxEb2N1bWVudEZyYWdtZW50OlcudUgsU2hhZG93Um9vdDpXLnVILERvY3VtZW50VHlwZTpXLnVILE5v
-ZGU6Vy51SCxOb2RlTGlzdDpXLkJILFJhZGlvTm9kZUxpc3Q6Vy5CSCxIVE1MUGFyYWdyYXBoRWxlbWVu
-dDpXLlNOLFByb2dyZXNzRXZlbnQ6Vy5ldyxSZXNvdXJjZVByb2dyZXNzRXZlbnQ6Vy5ldyxIVE1MU2Vs
-ZWN0RWxlbWVudDpXLmxwLEhUTUxUYWJsZUVsZW1lbnQ6Vy5UYixIVE1MVGFibGVSb3dFbGVtZW50Olcu
-SXYsSFRNTFRhYmxlU2VjdGlvbkVsZW1lbnQ6Vy5XUCxIVE1MVGVtcGxhdGVFbGVtZW50OlcueVksQ29t
-cG9zaXRpb25FdmVudDpXLnc2LEZvY3VzRXZlbnQ6Vy53NixLZXlib2FyZEV2ZW50OlcudzYsVGV4dEV2
-ZW50OlcudzYsVG91Y2hFdmVudDpXLnc2LFVJRXZlbnQ6Vy53NixXaW5kb3c6Vy5LNSxET01XaW5kb3c6
-Vy5LNSxEZWRpY2F0ZWRXb3JrZXJHbG9iYWxTY29wZTpXLkNtLFNlcnZpY2VXb3JrZXJHbG9iYWxTY29w
-ZTpXLkNtLFNoYXJlZFdvcmtlckdsb2JhbFNjb3BlOlcuQ20sV29ya2VyR2xvYmFsU2NvcGU6Vy5DbSxB
-dHRyOlcuQ1EsQ2xpZW50UmVjdDpXLnc0LERPTVJlY3Q6Vy53NCxOYW1lZE5vZGVNYXA6Vy5yaCxNb3pO
-YW1lZEF0dHJNYXA6Vy5yaCxJREJLZXlSYW5nZTpQLmhGLFNWR1NjcmlwdEVsZW1lbnQ6UC5iQixTVkdB
-RWxlbWVudDpQLmQ1LFNWR0FuaW1hdGVFbGVtZW50OlAuZDUsU1ZHQW5pbWF0ZU1vdGlvbkVsZW1lbnQ6
-UC5kNSxTVkdBbmltYXRlVHJhbnNmb3JtRWxlbWVudDpQLmQ1LFNWR0FuaW1hdGlvbkVsZW1lbnQ6UC5k
-NSxTVkdDaXJjbGVFbGVtZW50OlAuZDUsU1ZHQ2xpcFBhdGhFbGVtZW50OlAuZDUsU1ZHRGVmc0VsZW1l
-bnQ6UC5kNSxTVkdEZXNjRWxlbWVudDpQLmQ1LFNWR0Rpc2NhcmRFbGVtZW50OlAuZDUsU1ZHRWxsaXBz
-ZUVsZW1lbnQ6UC5kNSxTVkdGRUJsZW5kRWxlbWVudDpQLmQ1LFNWR0ZFQ29sb3JNYXRyaXhFbGVtZW50
-OlAuZDUsU1ZHRkVDb21wb25lbnRUcmFuc2ZlckVsZW1lbnQ6UC5kNSxTVkdGRUNvbXBvc2l0ZUVsZW1l
-bnQ6UC5kNSxTVkdGRUNvbnZvbHZlTWF0cml4RWxlbWVudDpQLmQ1LFNWR0ZFRGlmZnVzZUxpZ2h0aW5n
-RWxlbWVudDpQLmQ1LFNWR0ZFRGlzcGxhY2VtZW50TWFwRWxlbWVudDpQLmQ1LFNWR0ZFRGlzdGFudExp
-Z2h0RWxlbWVudDpQLmQ1LFNWR0ZFRmxvb2RFbGVtZW50OlAuZDUsU1ZHRkVGdW5jQUVsZW1lbnQ6UC5k
-NSxTVkdGRUZ1bmNCRWxlbWVudDpQLmQ1LFNWR0ZFRnVuY0dFbGVtZW50OlAuZDUsU1ZHRkVGdW5jUkVs
-ZW1lbnQ6UC5kNSxTVkdGRUdhdXNzaWFuQmx1ckVsZW1lbnQ6UC5kNSxTVkdGRUltYWdlRWxlbWVudDpQ
-LmQ1LFNWR0ZFTWVyZ2VFbGVtZW50OlAuZDUsU1ZHRkVNZXJnZU5vZGVFbGVtZW50OlAuZDUsU1ZHRkVN
-b3JwaG9sb2d5RWxlbWVudDpQLmQ1LFNWR0ZFT2Zmc2V0RWxlbWVudDpQLmQ1LFNWR0ZFUG9pbnRMaWdo
-dEVsZW1lbnQ6UC5kNSxTVkdGRVNwZWN1bGFyTGlnaHRpbmdFbGVtZW50OlAuZDUsU1ZHRkVTcG90TGln
-aHRFbGVtZW50OlAuZDUsU1ZHRkVUaWxlRWxlbWVudDpQLmQ1LFNWR0ZFVHVyYnVsZW5jZUVsZW1lbnQ6
-UC5kNSxTVkdGaWx0ZXJFbGVtZW50OlAuZDUsU1ZHRm9yZWlnbk9iamVjdEVsZW1lbnQ6UC5kNSxTVkdH
-RWxlbWVudDpQLmQ1LFNWR0dlb21ldHJ5RWxlbWVudDpQLmQ1LFNWR0dyYXBoaWNzRWxlbWVudDpQLmQ1
-LFNWR0ltYWdlRWxlbWVudDpQLmQ1LFNWR0xpbmVFbGVtZW50OlAuZDUsU1ZHTGluZWFyR3JhZGllbnRF
-bGVtZW50OlAuZDUsU1ZHTWFya2VyRWxlbWVudDpQLmQ1LFNWR01hc2tFbGVtZW50OlAuZDUsU1ZHTWV0
-YWRhdGFFbGVtZW50OlAuZDUsU1ZHUGF0aEVsZW1lbnQ6UC5kNSxTVkdQYXR0ZXJuRWxlbWVudDpQLmQ1
-LFNWR1BvbHlnb25FbGVtZW50OlAuZDUsU1ZHUG9seWxpbmVFbGVtZW50OlAuZDUsU1ZHUmFkaWFsR3Jh
-ZGllbnRFbGVtZW50OlAuZDUsU1ZHUmVjdEVsZW1lbnQ6UC5kNSxTVkdTZXRFbGVtZW50OlAuZDUsU1ZH
-U3RvcEVsZW1lbnQ6UC5kNSxTVkdTdHlsZUVsZW1lbnQ6UC5kNSxTVkdTVkdFbGVtZW50OlAuZDUsU1ZH
-U3dpdGNoRWxlbWVudDpQLmQ1LFNWR1N5bWJvbEVsZW1lbnQ6UC5kNSxTVkdUU3BhbkVsZW1lbnQ6UC5k
-NSxTVkdUZXh0Q29udGVudEVsZW1lbnQ6UC5kNSxTVkdUZXh0RWxlbWVudDpQLmQ1LFNWR1RleHRQYXRo
-RWxlbWVudDpQLmQ1LFNWR1RleHRQb3NpdGlvbmluZ0VsZW1lbnQ6UC5kNSxTVkdUaXRsZUVsZW1lbnQ6
-UC5kNSxTVkdVc2VFbGVtZW50OlAuZDUsU1ZHVmlld0VsZW1lbnQ6UC5kNSxTVkdHcmFkaWVudEVsZW1l
-bnQ6UC5kNSxTVkdDb21wb25lbnRUcmFuc2ZlckZ1bmN0aW9uRWxlbWVudDpQLmQ1LFNWR0ZFRHJvcFNo
-YWRvd0VsZW1lbnQ6UC5kNSxTVkdNUGF0aEVsZW1lbnQ6UC5kNSxTVkdFbGVtZW50OlAuZDV9KQpodW5r
-SGVscGVycy5zZXRPclVwZGF0ZUxlYWZUYWdzKHtET01FcnJvcjp0cnVlLERPTUltcGxlbWVudGF0aW9u
-OnRydWUsTWVkaWFFcnJvcjp0cnVlLE5hdmlnYXRvcjp0cnVlLE5hdmlnYXRvckNvbmN1cnJlbnRIYXJk
-d2FyZTp0cnVlLE5hdmlnYXRvclVzZXJNZWRpYUVycm9yOnRydWUsT3ZlcmNvbnN0cmFpbmVkRXJyb3I6
-dHJ1ZSxQb3NpdGlvbkVycm9yOnRydWUsUmFuZ2U6dHJ1ZSxTUUxFcnJvcjp0cnVlLERhdGFWaWV3OnRy
-dWUsQXJyYXlCdWZmZXJWaWV3OmZhbHNlLEZsb2F0MzJBcnJheTp0cnVlLEZsb2F0NjRBcnJheTp0cnVl
-LEludDE2QXJyYXk6dHJ1ZSxJbnQzMkFycmF5OnRydWUsSW50OEFycmF5OnRydWUsVWludDE2QXJyYXk6
-dHJ1ZSxVaW50MzJBcnJheTp0cnVlLFVpbnQ4Q2xhbXBlZEFycmF5OnRydWUsQ2FudmFzUGl4ZWxBcnJh
-eTp0cnVlLFVpbnQ4QXJyYXk6ZmFsc2UsSFRNTEF1ZGlvRWxlbWVudDp0cnVlLEhUTUxCUkVsZW1lbnQ6
-dHJ1ZSxIVE1MQnV0dG9uRWxlbWVudDp0cnVlLEhUTUxDYW52YXNFbGVtZW50OnRydWUsSFRNTENvbnRl
-bnRFbGVtZW50OnRydWUsSFRNTERMaXN0RWxlbWVudDp0cnVlLEhUTUxEYXRhRWxlbWVudDp0cnVlLEhU
-TUxEYXRhTGlzdEVsZW1lbnQ6dHJ1ZSxIVE1MRGV0YWlsc0VsZW1lbnQ6dHJ1ZSxIVE1MRGlhbG9nRWxl
-bWVudDp0cnVlLEhUTUxEaXZFbGVtZW50OnRydWUsSFRNTEVtYmVkRWxlbWVudDp0cnVlLEhUTUxGaWVs
-ZFNldEVsZW1lbnQ6dHJ1ZSxIVE1MSFJFbGVtZW50OnRydWUsSFRNTEhlYWRFbGVtZW50OnRydWUsSFRN
-TEhlYWRpbmdFbGVtZW50OnRydWUsSFRNTEh0bWxFbGVtZW50OnRydWUsSFRNTElGcmFtZUVsZW1lbnQ6
-dHJ1ZSxIVE1MSW1hZ2VFbGVtZW50OnRydWUsSFRNTElucHV0RWxlbWVudDp0cnVlLEhUTUxMSUVsZW1l
-bnQ6dHJ1ZSxIVE1MTGFiZWxFbGVtZW50OnRydWUsSFRNTExlZ2VuZEVsZW1lbnQ6dHJ1ZSxIVE1MTGlu
-a0VsZW1lbnQ6dHJ1ZSxIVE1MTWFwRWxlbWVudDp0cnVlLEhUTUxNZWRpYUVsZW1lbnQ6dHJ1ZSxIVE1M
-TWVudUVsZW1lbnQ6dHJ1ZSxIVE1MTWV0YUVsZW1lbnQ6dHJ1ZSxIVE1MTWV0ZXJFbGVtZW50OnRydWUs
-SFRNTE1vZEVsZW1lbnQ6dHJ1ZSxIVE1MT0xpc3RFbGVtZW50OnRydWUsSFRNTE9iamVjdEVsZW1lbnQ6
-dHJ1ZSxIVE1MT3B0R3JvdXBFbGVtZW50OnRydWUsSFRNTE9wdGlvbkVsZW1lbnQ6dHJ1ZSxIVE1MT3V0
-cHV0RWxlbWVudDp0cnVlLEhUTUxQYXJhbUVsZW1lbnQ6dHJ1ZSxIVE1MUGljdHVyZUVsZW1lbnQ6dHJ1
-ZSxIVE1MUHJlRWxlbWVudDp0cnVlLEhUTUxQcm9ncmVzc0VsZW1lbnQ6dHJ1ZSxIVE1MUXVvdGVFbGVt
-ZW50OnRydWUsSFRNTFNjcmlwdEVsZW1lbnQ6dHJ1ZSxIVE1MU2hhZG93RWxlbWVudDp0cnVlLEhUTUxT
-bG90RWxlbWVudDp0cnVlLEhUTUxTb3VyY2VFbGVtZW50OnRydWUsSFRNTFNwYW5FbGVtZW50OnRydWUs
-SFRNTFN0eWxlRWxlbWVudDp0cnVlLEhUTUxUYWJsZUNhcHRpb25FbGVtZW50OnRydWUsSFRNTFRhYmxl
-Q2VsbEVsZW1lbnQ6dHJ1ZSxIVE1MVGFibGVEYXRhQ2VsbEVsZW1lbnQ6dHJ1ZSxIVE1MVGFibGVIZWFk
-ZXJDZWxsRWxlbWVudDp0cnVlLEhUTUxUYWJsZUNvbEVsZW1lbnQ6dHJ1ZSxIVE1MVGV4dEFyZWFFbGVt
-ZW50OnRydWUsSFRNTFRpbWVFbGVtZW50OnRydWUsSFRNTFRpdGxlRWxlbWVudDp0cnVlLEhUTUxUcmFj
-a0VsZW1lbnQ6dHJ1ZSxIVE1MVUxpc3RFbGVtZW50OnRydWUsSFRNTFVua25vd25FbGVtZW50OnRydWUs
-SFRNTFZpZGVvRWxlbWVudDp0cnVlLEhUTUxEaXJlY3RvcnlFbGVtZW50OnRydWUsSFRNTEZvbnRFbGVt
-ZW50OnRydWUsSFRNTEZyYW1lRWxlbWVudDp0cnVlLEhUTUxGcmFtZVNldEVsZW1lbnQ6dHJ1ZSxIVE1M
-TWFycXVlZUVsZW1lbnQ6dHJ1ZSxIVE1MRWxlbWVudDpmYWxzZSxIVE1MQW5jaG9yRWxlbWVudDp0cnVl
-LEhUTUxBcmVhRWxlbWVudDp0cnVlLEhUTUxCYXNlRWxlbWVudDp0cnVlLEJsb2I6ZmFsc2UsSFRNTEJv
-ZHlFbGVtZW50OnRydWUsQ0RBVEFTZWN0aW9uOnRydWUsQ2hhcmFjdGVyRGF0YTp0cnVlLENvbW1lbnQ6
-dHJ1ZSxQcm9jZXNzaW5nSW5zdHJ1Y3Rpb246dHJ1ZSxUZXh0OnRydWUsQ1NTU3R5bGVEZWNsYXJhdGlv
-bjp0cnVlLE1TU3R5bGVDU1NQcm9wZXJ0aWVzOnRydWUsQ1NTMlByb3BlcnRpZXM6dHJ1ZSxYTUxEb2N1
-bWVudDp0cnVlLERvY3VtZW50OmZhbHNlLERPTUV4Y2VwdGlvbjp0cnVlLERPTVJlY3RSZWFkT25seTpm
-YWxzZSxET01Ub2tlbkxpc3Q6dHJ1ZSxFbGVtZW50OmZhbHNlLEFib3J0UGF5bWVudEV2ZW50OnRydWUs
-QW5pbWF0aW9uRXZlbnQ6dHJ1ZSxBbmltYXRpb25QbGF5YmFja0V2ZW50OnRydWUsQXBwbGljYXRpb25D
-YWNoZUVycm9yRXZlbnQ6dHJ1ZSxCYWNrZ3JvdW5kRmV0Y2hDbGlja0V2ZW50OnRydWUsQmFja2dyb3Vu
-ZEZldGNoRXZlbnQ6dHJ1ZSxCYWNrZ3JvdW5kRmV0Y2hGYWlsRXZlbnQ6dHJ1ZSxCYWNrZ3JvdW5kRmV0
-Y2hlZEV2ZW50OnRydWUsQmVmb3JlSW5zdGFsbFByb21wdEV2ZW50OnRydWUsQmVmb3JlVW5sb2FkRXZl
-bnQ6dHJ1ZSxCbG9iRXZlbnQ6dHJ1ZSxDYW5NYWtlUGF5bWVudEV2ZW50OnRydWUsQ2xpcGJvYXJkRXZl
-bnQ6dHJ1ZSxDbG9zZUV2ZW50OnRydWUsQ3VzdG9tRXZlbnQ6dHJ1ZSxEZXZpY2VNb3Rpb25FdmVudDp0
-cnVlLERldmljZU9yaWVudGF0aW9uRXZlbnQ6dHJ1ZSxFcnJvckV2ZW50OnRydWUsRXh0ZW5kYWJsZUV2
-ZW50OnRydWUsRXh0ZW5kYWJsZU1lc3NhZ2VFdmVudDp0cnVlLEZldGNoRXZlbnQ6dHJ1ZSxGb250RmFj
-ZVNldExvYWRFdmVudDp0cnVlLEZvcmVpZ25GZXRjaEV2ZW50OnRydWUsR2FtZXBhZEV2ZW50OnRydWUs
-SGFzaENoYW5nZUV2ZW50OnRydWUsSW5zdGFsbEV2ZW50OnRydWUsTWVkaWFFbmNyeXB0ZWRFdmVudDp0
-cnVlLE1lZGlhS2V5TWVzc2FnZUV2ZW50OnRydWUsTWVkaWFRdWVyeUxpc3RFdmVudDp0cnVlLE1lZGlh
-U3RyZWFtRXZlbnQ6dHJ1ZSxNZWRpYVN0cmVhbVRyYWNrRXZlbnQ6dHJ1ZSxNZXNzYWdlRXZlbnQ6dHJ1
-ZSxNSURJQ29ubmVjdGlvbkV2ZW50OnRydWUsTUlESU1lc3NhZ2VFdmVudDp0cnVlLE11dGF0aW9uRXZl
-bnQ6dHJ1ZSxOb3RpZmljYXRpb25FdmVudDp0cnVlLFBhZ2VUcmFuc2l0aW9uRXZlbnQ6dHJ1ZSxQYXlt
-ZW50UmVxdWVzdEV2ZW50OnRydWUsUGF5bWVudFJlcXVlc3RVcGRhdGVFdmVudDp0cnVlLFBvcFN0YXRl
-RXZlbnQ6dHJ1ZSxQcmVzZW50YXRpb25Db25uZWN0aW9uQXZhaWxhYmxlRXZlbnQ6dHJ1ZSxQcmVzZW50
-YXRpb25Db25uZWN0aW9uQ2xvc2VFdmVudDp0cnVlLFByb21pc2VSZWplY3Rpb25FdmVudDp0cnVlLFB1
-c2hFdmVudDp0cnVlLFJUQ0RhdGFDaGFubmVsRXZlbnQ6dHJ1ZSxSVENEVE1GVG9uZUNoYW5nZUV2ZW50
-OnRydWUsUlRDUGVlckNvbm5lY3Rpb25JY2VFdmVudDp0cnVlLFJUQ1RyYWNrRXZlbnQ6dHJ1ZSxTZWN1
-cml0eVBvbGljeVZpb2xhdGlvbkV2ZW50OnRydWUsU2Vuc29yRXJyb3JFdmVudDp0cnVlLFNwZWVjaFJl
-Y29nbml0aW9uRXJyb3I6dHJ1ZSxTcGVlY2hSZWNvZ25pdGlvbkV2ZW50OnRydWUsU3BlZWNoU3ludGhl
-c2lzRXZlbnQ6dHJ1ZSxTdG9yYWdlRXZlbnQ6dHJ1ZSxTeW5jRXZlbnQ6dHJ1ZSxUcmFja0V2ZW50OnRy
-dWUsVHJhbnNpdGlvbkV2ZW50OnRydWUsV2ViS2l0VHJhbnNpdGlvbkV2ZW50OnRydWUsVlJEZXZpY2VF
-dmVudDp0cnVlLFZSRGlzcGxheUV2ZW50OnRydWUsVlJTZXNzaW9uRXZlbnQ6dHJ1ZSxNb2pvSW50ZXJm
-YWNlUmVxdWVzdEV2ZW50OnRydWUsVVNCQ29ubmVjdGlvbkV2ZW50OnRydWUsSURCVmVyc2lvbkNoYW5n
-ZUV2ZW50OnRydWUsQXVkaW9Qcm9jZXNzaW5nRXZlbnQ6dHJ1ZSxPZmZsaW5lQXVkaW9Db21wbGV0aW9u
-RXZlbnQ6dHJ1ZSxXZWJHTENvbnRleHRFdmVudDp0cnVlLEV2ZW50OmZhbHNlLElucHV0RXZlbnQ6ZmFs
-c2UsRXZlbnRUYXJnZXQ6ZmFsc2UsRmlsZTp0cnVlLEhUTUxGb3JtRWxlbWVudDp0cnVlLEhpc3Rvcnk6
-dHJ1ZSxIVE1MRG9jdW1lbnQ6dHJ1ZSxYTUxIdHRwUmVxdWVzdDp0cnVlLFhNTEh0dHBSZXF1ZXN0RXZl
-bnRUYXJnZXQ6ZmFsc2UsSW1hZ2VEYXRhOnRydWUsTG9jYXRpb246dHJ1ZSxNb3VzZUV2ZW50OnRydWUs
-RHJhZ0V2ZW50OnRydWUsUG9pbnRlckV2ZW50OnRydWUsV2hlZWxFdmVudDp0cnVlLERvY3VtZW50RnJh
-Z21lbnQ6dHJ1ZSxTaGFkb3dSb290OnRydWUsRG9jdW1lbnRUeXBlOnRydWUsTm9kZTpmYWxzZSxOb2Rl
-TGlzdDp0cnVlLFJhZGlvTm9kZUxpc3Q6dHJ1ZSxIVE1MUGFyYWdyYXBoRWxlbWVudDp0cnVlLFByb2dy
-ZXNzRXZlbnQ6dHJ1ZSxSZXNvdXJjZVByb2dyZXNzRXZlbnQ6dHJ1ZSxIVE1MU2VsZWN0RWxlbWVudDp0
-cnVlLEhUTUxUYWJsZUVsZW1lbnQ6dHJ1ZSxIVE1MVGFibGVSb3dFbGVtZW50OnRydWUsSFRNTFRhYmxl
-U2VjdGlvbkVsZW1lbnQ6dHJ1ZSxIVE1MVGVtcGxhdGVFbGVtZW50OnRydWUsQ29tcG9zaXRpb25FdmVu
-dDp0cnVlLEZvY3VzRXZlbnQ6dHJ1ZSxLZXlib2FyZEV2ZW50OnRydWUsVGV4dEV2ZW50OnRydWUsVG91
-Y2hFdmVudDp0cnVlLFVJRXZlbnQ6ZmFsc2UsV2luZG93OnRydWUsRE9NV2luZG93OnRydWUsRGVkaWNh
-dGVkV29ya2VyR2xvYmFsU2NvcGU6dHJ1ZSxTZXJ2aWNlV29ya2VyR2xvYmFsU2NvcGU6dHJ1ZSxTaGFy
-ZWRXb3JrZXJHbG9iYWxTY29wZTp0cnVlLFdvcmtlckdsb2JhbFNjb3BlOnRydWUsQXR0cjp0cnVlLENs
-aWVudFJlY3Q6dHJ1ZSxET01SZWN0OnRydWUsTmFtZWROb2RlTWFwOnRydWUsTW96TmFtZWRBdHRyTWFw
-OnRydWUsSURCS2V5UmFuZ2U6dHJ1ZSxTVkdTY3JpcHRFbGVtZW50OnRydWUsU1ZHQUVsZW1lbnQ6dHJ1
-ZSxTVkdBbmltYXRlRWxlbWVudDp0cnVlLFNWR0FuaW1hdGVNb3Rpb25FbGVtZW50OnRydWUsU1ZHQW5p
-bWF0ZVRyYW5zZm9ybUVsZW1lbnQ6dHJ1ZSxTVkdBbmltYXRpb25FbGVtZW50OnRydWUsU1ZHQ2lyY2xl
-RWxlbWVudDp0cnVlLFNWR0NsaXBQYXRoRWxlbWVudDp0cnVlLFNWR0RlZnNFbGVtZW50OnRydWUsU1ZH
-RGVzY0VsZW1lbnQ6dHJ1ZSxTVkdEaXNjYXJkRWxlbWVudDp0cnVlLFNWR0VsbGlwc2VFbGVtZW50OnRy
-dWUsU1ZHRkVCbGVuZEVsZW1lbnQ6dHJ1ZSxTVkdGRUNvbG9yTWF0cml4RWxlbWVudDp0cnVlLFNWR0ZF
-Q29tcG9uZW50VHJhbnNmZXJFbGVtZW50OnRydWUsU1ZHRkVDb21wb3NpdGVFbGVtZW50OnRydWUsU1ZH
-RkVDb252b2x2ZU1hdHJpeEVsZW1lbnQ6dHJ1ZSxTVkdGRURpZmZ1c2VMaWdodGluZ0VsZW1lbnQ6dHJ1
-ZSxTVkdGRURpc3BsYWNlbWVudE1hcEVsZW1lbnQ6dHJ1ZSxTVkdGRURpc3RhbnRMaWdodEVsZW1lbnQ6
-dHJ1ZSxTVkdGRUZsb29kRWxlbWVudDp0cnVlLFNWR0ZFRnVuY0FFbGVtZW50OnRydWUsU1ZHRkVGdW5j
-QkVsZW1lbnQ6dHJ1ZSxTVkdGRUZ1bmNHRWxlbWVudDp0cnVlLFNWR0ZFRnVuY1JFbGVtZW50OnRydWUs
-U1ZHRkVHYXVzc2lhbkJsdXJFbGVtZW50OnRydWUsU1ZHRkVJbWFnZUVsZW1lbnQ6dHJ1ZSxTVkdGRU1l
-cmdlRWxlbWVudDp0cnVlLFNWR0ZFTWVyZ2VOb2RlRWxlbWVudDp0cnVlLFNWR0ZFTW9ycGhvbG9neUVs
-ZW1lbnQ6dHJ1ZSxTVkdGRU9mZnNldEVsZW1lbnQ6dHJ1ZSxTVkdGRVBvaW50TGlnaHRFbGVtZW50OnRy
-dWUsU1ZHRkVTcGVjdWxhckxpZ2h0aW5nRWxlbWVudDp0cnVlLFNWR0ZFU3BvdExpZ2h0RWxlbWVudDp0
-cnVlLFNWR0ZFVGlsZUVsZW1lbnQ6dHJ1ZSxTVkdGRVR1cmJ1bGVuY2VFbGVtZW50OnRydWUsU1ZHRmls
-dGVyRWxlbWVudDp0cnVlLFNWR0ZvcmVpZ25PYmplY3RFbGVtZW50OnRydWUsU1ZHR0VsZW1lbnQ6dHJ1
-ZSxTVkdHZW9tZXRyeUVsZW1lbnQ6dHJ1ZSxTVkdHcmFwaGljc0VsZW1lbnQ6dHJ1ZSxTVkdJbWFnZUVs
-ZW1lbnQ6dHJ1ZSxTVkdMaW5lRWxlbWVudDp0cnVlLFNWR0xpbmVhckdyYWRpZW50RWxlbWVudDp0cnVl
-LFNWR01hcmtlckVsZW1lbnQ6dHJ1ZSxTVkdNYXNrRWxlbWVudDp0cnVlLFNWR01ldGFkYXRhRWxlbWVu
-dDp0cnVlLFNWR1BhdGhFbGVtZW50OnRydWUsU1ZHUGF0dGVybkVsZW1lbnQ6dHJ1ZSxTVkdQb2x5Z29u
-RWxlbWVudDp0cnVlLFNWR1BvbHlsaW5lRWxlbWVudDp0cnVlLFNWR1JhZGlhbEdyYWRpZW50RWxlbWVu
-dDp0cnVlLFNWR1JlY3RFbGVtZW50OnRydWUsU1ZHU2V0RWxlbWVudDp0cnVlLFNWR1N0b3BFbGVtZW50
-OnRydWUsU1ZHU3R5bGVFbGVtZW50OnRydWUsU1ZHU1ZHRWxlbWVudDp0cnVlLFNWR1N3aXRjaEVsZW1l
-bnQ6dHJ1ZSxTVkdTeW1ib2xFbGVtZW50OnRydWUsU1ZHVFNwYW5FbGVtZW50OnRydWUsU1ZHVGV4dENv
-bnRlbnRFbGVtZW50OnRydWUsU1ZHVGV4dEVsZW1lbnQ6dHJ1ZSxTVkdUZXh0UGF0aEVsZW1lbnQ6dHJ1
-ZSxTVkdUZXh0UG9zaXRpb25pbmdFbGVtZW50OnRydWUsU1ZHVGl0bGVFbGVtZW50OnRydWUsU1ZHVXNl
-RWxlbWVudDp0cnVlLFNWR1ZpZXdFbGVtZW50OnRydWUsU1ZHR3JhZGllbnRFbGVtZW50OnRydWUsU1ZH
-Q29tcG9uZW50VHJhbnNmZXJGdW5jdGlvbkVsZW1lbnQ6dHJ1ZSxTVkdGRURyb3BTaGFkb3dFbGVtZW50
-OnRydWUsU1ZHTVBhdGhFbGVtZW50OnRydWUsU1ZHRWxlbWVudDpmYWxzZX0pCkguYjAuJG5hdGl2ZVN1
-cGVyY2xhc3NUYWc9IkFycmF5QnVmZmVyVmlldyIKSC5SRy4kbmF0aXZlU3VwZXJjbGFzc1RhZz0iQXJy
-YXlCdWZmZXJWaWV3IgpILlZQLiRuYXRpdmVTdXBlcmNsYXNzVGFnPSJBcnJheUJ1ZmZlclZpZXciCkgu
-RGcuJG5hdGl2ZVN1cGVyY2xhc3NUYWc9IkFycmF5QnVmZmVyVmlldyIKSC5XQi4kbmF0aXZlU3VwZXJj
-bGFzc1RhZz0iQXJyYXlCdWZmZXJWaWV3IgpILlpHLiRuYXRpdmVTdXBlcmNsYXNzVGFnPSJBcnJheUJ1
-ZmZlclZpZXciCkguUGcuJG5hdGl2ZVN1cGVyY2xhc3NUYWc9IkFycmF5QnVmZmVyVmlldyJ9KSgpCmNv
-bnZlcnRBbGxUb0Zhc3RPYmplY3QodykKY29udmVydFRvRmFzdE9iamVjdCgkKTsoZnVuY3Rpb24oYSl7
-aWYodHlwZW9mIGRvY3VtZW50PT09InVuZGVmaW5lZCIpe2EobnVsbCkKcmV0dXJufWlmKHR5cGVvZiBk
-b2N1bWVudC5jdXJyZW50U2NyaXB0IT0ndW5kZWZpbmVkJyl7YShkb2N1bWVudC5jdXJyZW50U2NyaXB0
-KQpyZXR1cm59dmFyIHQ9ZG9jdW1lbnQuc2NyaXB0cwpmdW5jdGlvbiBvbkxvYWQoYil7Zm9yKHZhciBy
-PTA7cjx0Lmxlbmd0aDsrK3IpdFtyXS5yZW1vdmVFdmVudExpc3RlbmVyKCJsb2FkIixvbkxvYWQsZmFs
-c2UpCmEoYi50YXJnZXQpfWZvcih2YXIgcz0wO3M8dC5sZW5ndGg7KytzKXRbc10uYWRkRXZlbnRMaXN0
-ZW5lcigibG9hZCIsb25Mb2FkLGZhbHNlKX0pKGZ1bmN0aW9uKGEpe3YuY3VycmVudFNjcmlwdD1hCmlm
-KHR5cGVvZiBkYXJ0TWFpblJ1bm5lcj09PSJmdW5jdGlvbiIpZGFydE1haW5SdW5uZXIoTC5JcSxbXSkK
-ZWxzZSBMLklxKFtdKX0pfSkoKQovLyMgc291cmNlTWFwcGluZ1VSTD1taWdyYXRpb24uanMubWFwCg==
+SUMucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQ9Si5xRih1LmcuYShhKSkscz10LiR0aQpz
+LkMoIn4oMSk/IikuYShMLmlTKCkpCnUuWi5hKG51bGwpClcuSkUodC5hLHQuYixMLmlTKCksITEscy5j
+KX0sCiRTOjR9CkwuTDEucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dS5FLmEoYSkKdGhpcy5hLmFN
+KDAsdGhpcy5iKX0sCiRTOjQ0fQpMLm5ULnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7TC5Gcih0aGlz
+LmEuYSx0aGlzLmIsdGhpcy5jKX0sCiRTOjB9CkwuTlkucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXtM
+LkZyKHRoaXMuYS5hLG51bGwsbnVsbCl9LAokUzowfQpMLmVYLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9u
+KGEpe3UuZy5hKGEpCiQuekIoKS50b1N0cmluZwp1LmRILmEoJC5vdygpLnEoMCwiaGxqcyIpKS5WNygi
+aGlnaGxpZ2h0QmxvY2siLFthXSl9LAokUzo0fQpMLkRULnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEp
+e3ZhciB0LHMKdS5ELmEoYSkKdD1hLnN0YXR1cwppZih0PT09MjAwKXt0PUMuQ3QucFcoMCxhLnJlc3Bv
+bnNlVGV4dCxudWxsKQpzPUouVTYodCkKTC5UMShuZXcgVS5kMihVLmpmKHMucSh0LCJlZGl0cyIpKSxI
+Lmgocy5xKHQsImV4cGxhbmF0aW9uIikpLEgudVAocy5xKHQsImxpbmUiKSksSC5oKHMucSh0LCJwYXRo
+IikpLFUuTmQocy5xKHQsInRyYWNlcyIpKSkpCkwuRnIodGhpcy5hLHRoaXMuYix0aGlzLmMpCkwueVgo
+Ii5lZGl0LXBhbmVsIC5wYW5lbC1jb250ZW50IiwhMSl9ZWxzZSBDLm9sLlV4KHdpbmRvdywiUmVxdWVz
+dCBmYWlsZWQ7IHN0YXR1cyBvZiAiK3QpfSwKJFM6OH0KTC5lSC5wcm90b3R5cGU9ewokMjpmdW5jdGlv
+bihhLGIpe0wucUooImxvYWRSZWdpb25FeHBsYW5hdGlvbjogIitILkVqKGEpLGIpCkMub2wuVXgod2lu
+ZG93LCJDb3VsZCBub3QgbG9hZCAiK0guRWoodGhpcy5hKSsiICgiK0guRWooYSkrIikuIil9LAokQzoi
+JDIiLAokUjoyLAokUzoyfQpMLnl1LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0LHMscj10
+aGlzCnUuRC5hKGEpCnQ9YS5zdGF0dXMKaWYodD09PTIwMCl7cz1yLmEKTC5CRShzLEIuWWYodS5iby5h
+KEMuQ3QucFcoMCxhLnJlc3BvbnNlVGV4dCxudWxsKSkpLHIuYikKdD1yLmMKTC5mRyh0LHIuZCkKTC5C
+WChDLnhCLnRnKHMsIj8iKT9DLnhCLk5qKHMsMCxDLnhCLk9ZKHMsIj8iKSk6cyx0KQp0PXIuZQppZih0
+IT1udWxsKXQuJDAoKX1lbHNlIEMub2wuVXgod2luZG93LCJSZXF1ZXN0IGZhaWxlZDsgc3RhdHVzIG9m
+ICIrdCl9LAokUzo4fQpMLnpELnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7TC5xSigibG9hZEZp
+bGU6ICIrSC5FaihhKSxiKQpDLm9sLlV4KHdpbmRvdywiQ291bGQgbm90IGxvYWQgIit0aGlzLmErIiAo
+IitILkVqKGEpKyIpLiIpfSwKJEM6IiQyIiwKJFI6MiwKJFM6Mn0KTC5UVy5wcm90b3R5cGU9ewokMTpm
+dW5jdGlvbihhKXt2YXIgdCxzLHIKdS5ELmEoYSkKdD1hLnN0YXR1cwppZih0PT09MjAwKXtzPUMuQ3Qu
+cFcoMCxhLnJlc3BvbnNlVGV4dCxudWxsKQpyPWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoIi5uYXYtdHJl
+ZSIpCkoubDUociwiIikKTC50WChyLEwubUsocykpfWVsc2UgQy5vbC5VeCh3aW5kb3csIlJlcXVlc3Qg
+ZmFpbGVkOyBzdGF0dXMgb2YgIit0KX0sCiRTOjh9CkwueHIucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24o
+YSxiKXtMLnFKKCJsb2FkTmF2aWdhdGlvblRyZWU6ICIrSC5FaihhKSxiKQpDLm9sLlV4KHdpbmRvdywi
+Q291bGQgbm90IGxvYWQgIit0aGlzLmErIiAoIitILkVqKGEpKyIpLiIpfSwKJEM6IiQyIiwKJFI6MiwK
+JFM6Mn0KTC5FRS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdCxzCnUuTy5hKGEpCnQ9dGhp
+cy5hCnM9dGhpcy5iCkwuYWYod2luZG93LmxvY2F0aW9uLnBhdGhuYW1lLHQscywhMCxuZXcgTC5RTCh0
+LHMpKQpMLmhYKHRoaXMuYyx0LHMpfSwKJFM6M30KTC5RTC5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigp
+e0wuRnIod2luZG93LmxvY2F0aW9uLnBhdGhuYW1lLHRoaXMuYSx0aGlzLmIpfSwKJFM6MH0KTC5WUy5w
+cm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdCxzPSJzZWxlY3RlZC1maWxlIgp1LmcuYShhKQph
+LnRvU3RyaW5nCnQ9Si5ZRShhKQppZihhLmdldEF0dHJpYnV0ZSgiZGF0YS0iK25ldyBXLlN5KG5ldyBX
+Lmk3KGEpKS5PKCJuYW1lIikpPT09dGhpcy5hLmEpdC5nUChhKS5pKDAscykKZWxzZSB0LmdQKGEpLlIo
+MCxzKX0sCiRTOjR9CkwuVEQucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIEwudDIodS5P
+LmEoYSksITAsbnVsbCl9LAokUzoxN30KTC5YQS5wcm90b3R5cGU9ewpFYjpmdW5jdGlvbihhLGIsYyl7
+cmV0dXJuITB9LAppMDpmdW5jdGlvbihhKXtyZXR1cm4hMH0sCiRpa0Y6MX0KTC5aWi5wcm90b3R5cGU9
+e30KTC5POS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmJ9fQpNLmxJLnByb3Rv
+dHlwZT17CldPOmZ1bmN0aW9uKGEsYil7dmFyIHQscz1udWxsCk0uWUYoImFic29sdXRlIixILlZNKFti
+LG51bGwsbnVsbCxudWxsLG51bGwsbnVsbCxudWxsXSx1LmkpKQp0PXRoaXMuYQp0PXQuWXIoYik+MCYm
+IXQuaEsoYikKaWYodClyZXR1cm4gYgp0PUQuUlgoKQpyZXR1cm4gdGhpcy5xNygwLHQsYixzLHMscyxz
+LHMscyl9LAp0TTpmdW5jdGlvbihhKXt2YXIgdCxzLHI9WC5DTChhLHRoaXMuYSkKci5JVigpCnQ9ci5k
+CnM9dC5sZW5ndGgKaWYocz09PTApe3Q9ci5iCnJldHVybiB0PT1udWxsPyIuIjp0fWlmKHM9PT0xKXt0
+PXIuYgpyZXR1cm4gdD09bnVsbD8iLiI6dH1pZigwPj1zKXJldHVybiBILk9IKHQsLTEpCnQucG9wKCkK
+Qy5ObS5tdihyLmUpCnIuSVYoKQpyZXR1cm4gci53KDApfSwKcTc6ZnVuY3Rpb24oYSxiLGMsZCxlLGYs
+ZyxoLGkpe3ZhciB0PUguVk0oW2IsYyxkLGUsZixnLGgsaV0sdS5pKQpNLllGKCJqb2luIix0KQpyZXR1
+cm4gdGhpcy5JUChuZXcgSC5VNSh0LHUuZ2YuYShuZXcgTS5NaSgpKSx1LmZpKSl9LApJUDpmdW5jdGlv
+bihhKXt2YXIgdCxzLHIscSxwLG8sbixtLGwKdS5lUy5hKGEpCmZvcih0PWEuJHRpLHM9dC5DKCJhMihj
+WC5FKSIpLmEobmV3IE0ucTcoKSkscj1hLmdreihhKSx0PW5ldyBILlNPKHIscyx0LkMoIlNPPGNYLkU+
+IikpLHM9dGhpcy5hLHE9ITEscD0hMSxvPSIiO3QuRigpOyl7bj1ILmgoci5nbCgpKQppZihzLmhLKG4p
+JiZwKXttPVguQ0wobixzKQpsPW8uY2hhckNvZGVBdCgwKT09MD9vOm8Kbz1DLnhCLk5qKGwsMCxzLlNw
+KGwsITApKQptLmI9bwppZihzLmRzKG8pKUMuTm0uWShtLmUsMCxzLmdtSSgpKQpvPSIiK20udygwKX1l
+bHNlIGlmKHMuWXIobik+MCl7cD0hcy5oSyhuKQpvPSIiK0guRWoobil9ZWxzZXtpZighKG4ubGVuZ3Ro
+PjAmJnMuVWQoblswXSkpKWlmKHEpbys9cy5nbUkoKQpvKz1ufXE9cy5kcyhuKX1yZXR1cm4gby5jaGFy
+Q29kZUF0KDApPT0wP286b30sCm81OmZ1bmN0aW9uKGEpe3ZhciB0CmlmKCF0aGlzLnkzKGEpKXJldHVy
+biBhCnQ9WC5DTChhLHRoaXMuYSkKdC5yUigpCnJldHVybiB0LncoMCl9LAp5MzpmdW5jdGlvbihhKXt2
+YXIgdCxzLHIscSxwLG8sbixtLGwsawphLnRvU3RyaW5nCnQ9dGhpcy5hCnM9dC5ZcihhKQppZihzIT09
+MCl7aWYodD09PSQuS2soKSlmb3Iocj0wO3I8czsrK3IpaWYoQy54Qi5XKGEscik9PT00NylyZXR1cm4h
+MApxPXMKcD00N31lbHNle3E9MApwPW51bGx9Zm9yKG89bmV3IEgucWooYSkuYSxuPW8ubGVuZ3RoLHI9
+cSxtPW51bGw7cjxuOysrcixtPXAscD1sKXtsPUMueEIubShvLHIpCmlmKHQucjQobCkpe2lmKHQ9PT0k
+LktrKCkmJmw9PT00NylyZXR1cm4hMAppZihwIT1udWxsJiZ0LnI0KHApKXJldHVybiEwCmlmKHA9PT00
+NilrPW09PW51bGx8fG09PT00Nnx8dC5yNChtKQplbHNlIGs9ITEKaWYoaylyZXR1cm4hMH19aWYocD09
+bnVsbClyZXR1cm4hMAppZih0LnI0KHApKXJldHVybiEwCmlmKHA9PT00Nil0PW09PW51bGx8fHQucjQo
+bSl8fG09PT00NgplbHNlIHQ9ITEKaWYodClyZXR1cm4hMApyZXR1cm4hMX0sCkhQOmZ1bmN0aW9uKGEs
+Yil7dmFyIHQscyxyLHEscCxvPXRoaXMsbj0nVW5hYmxlIHRvIGZpbmQgYSBwYXRoIHRvICInCmI9by5X
+TygwLGIpCnQ9by5hCmlmKHQuWXIoYik8PTAmJnQuWXIoYSk+MClyZXR1cm4gby5vNShhKQppZih0Llly
+KGEpPD0wfHx0LmhLKGEpKWE9by5XTygwLGEpCmlmKHQuWXIoYSk8PTAmJnQuWXIoYik+MCl0aHJvdyBI
+LmIoWC5JNyhuK0guRWooYSkrJyIgZnJvbSAiJytILkVqKGIpKyciLicpKQpzPVguQ0woYix0KQpzLnJS
+KCkKcj1YLkNMKGEsdCkKci5yUigpCnE9cy5kCmlmKHEubGVuZ3RoPjAmJkouUk0ocVswXSwiLiIpKXJl
+dHVybiByLncoMCkKcT1zLmIKcD1yLmIKaWYocSE9cClxPXE9PW51bGx8fHA9PW51bGx8fCF0Lk5jKHEs
+cCkKZWxzZSBxPSExCmlmKHEpcmV0dXJuIHIudygwKQp3aGlsZSghMCl7cT1zLmQKaWYocS5sZW5ndGg+
+MCl7cD1yLmQKcT1wLmxlbmd0aD4wJiZ0Lk5jKHFbMF0scFswXSl9ZWxzZSBxPSExCmlmKCFxKWJyZWFr
+CkMuTm0uVzQocy5kLDApCkMuTm0uVzQocy5lLDEpCkMuTm0uVzQoci5kLDApCkMuTm0uVzQoci5lLDEp
+fXE9cy5kCmlmKHEubGVuZ3RoPjAmJkouUk0ocVswXSwiLi4iKSl0aHJvdyBILmIoWC5JNyhuK0guRWoo
+YSkrJyIgZnJvbSAiJytILkVqKGIpKyciLicpKQpxPXUuWApDLk5tLlVHKHIuZCwwLFAuTzgocy5kLmxl
+bmd0aCwiLi4iLCExLHEpKQpDLk5tLlkoci5lLDAsIiIpCkMuTm0uVUcoci5lLDEsUC5POChzLmQubGVu
+Z3RoLHQuZ21JKCksITEscSkpCnQ9ci5kCnE9dC5sZW5ndGgKaWYocT09PTApcmV0dXJuIi4iCmlmKHE+
+MSYmSi5STShDLk5tLmdyWih0KSwiLiIpKXt0PXIuZAppZigwPj10Lmxlbmd0aClyZXR1cm4gSC5PSCh0
+LC0xKQp0LnBvcCgpCnQ9ci5lCkMuTm0ubXYodCkKQy5ObS5tdih0KQpDLk5tLmkodCwiIil9ci5iPSIi
+CnIuSVYoKQpyZXR1cm4gci53KDApfX0KTS5NaS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1
+cm4gSC5oKGEpIT1udWxsfSwKJFM6MTh9Ck0ucTcucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0
+dXJuIEguaChhKSE9PSIifSwKJFM6MTh9Ck0uTm8ucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7SC5o
+KGEpCnJldHVybiBhPT1udWxsPyJudWxsIjonIicrYSsnIid9LAokUzo0OH0KQi5mdi5wcm90b3R5cGU9
+ewp4WjpmdW5jdGlvbihhKXt2YXIgdCxzPXRoaXMuWXIoYSkKaWYocz4wKXJldHVybiBKLmxkKGEsMCxz
+KQppZih0aGlzLmhLKGEpKXtpZigwPj1hLmxlbmd0aClyZXR1cm4gSC5PSChhLDApCnQ9YVswXX1lbHNl
+IHQ9bnVsbApyZXR1cm4gdH0sCk5jOmZ1bmN0aW9uKGEsYil7cmV0dXJuIGE9PWJ9fQpYLldELnByb3Rv
+dHlwZT17CklWOmZ1bmN0aW9uKCl7dmFyIHQscyxyPXRoaXMKd2hpbGUoITApe3Q9ci5kCmlmKCEodC5s
+ZW5ndGghPT0wJiZKLlJNKEMuTm0uZ3JaKHQpLCIiKSkpYnJlYWsKdD1yLmQKaWYoMD49dC5sZW5ndGgp
+cmV0dXJuIEguT0godCwtMSkKdC5wb3AoKQpDLk5tLm12KHIuZSl9dD1yLmUKcz10Lmxlbmd0aAppZihz
+PjApQy5ObS5ZKHQscy0xLCIiKX0sCnJSOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscCxvLG4sbT10aGlz
+LGw9SC5WTShbXSx1LmkpCmZvcih0PW0uZCxzPXQubGVuZ3RoLHI9MCxxPTA7cTx0Lmxlbmd0aDt0Lmxl
+bmd0aD09PXN8fCgwLEgubGspKHQpLCsrcSl7cD10W3FdCm89Si5pYShwKQppZighKG8uRE4ocCwiLiIp
+fHxvLkROKHAsIiIpKSlpZihvLkROKHAsIi4uIikpaWYobC5sZW5ndGg+MClsLnBvcCgpCmVsc2UgKyty
+CmVsc2UgQy5ObS5pKGwscCl9aWYobS5iPT1udWxsKUMuTm0uVUcobCwwLFAuTzgociwiLi4iLCExLHUu
+WCkpCmlmKGwubGVuZ3RoPT09MCYmbS5iPT1udWxsKUMuTm0uaShsLCIuIikKbj1QLmRIKGwubGVuZ3Ro
+LG5ldyBYLnFSKG0pLCEwLHUuWCkKdD1tLmIKdD10IT1udWxsJiZsLmxlbmd0aD4wJiZtLmEuZHModCk/
+bS5hLmdtSSgpOiIiCkgudDYobikuYy5hKHQpCmlmKCEhbi5maXhlZCRsZW5ndGgpSC52aChQLkw0KCJp
+bnNlcnQiKSkKbi5zcGxpY2UoMCwwLHQpCm0uc25KKGwpCm0uc1BoKG4pCnQ9bS5iCmlmKHQhPW51bGwm
+Jm0uYT09PSQuS2soKSl7dC50b1N0cmluZwptLmI9SC55cyh0LCIvIiwiXFwiKX1tLklWKCl9LAp3OmZ1
+bmN0aW9uKGEpe3ZhciB0LHMscj10aGlzLHE9ci5iCnE9cSE9bnVsbD8iIitxOiIiCmZvcih0PTA7dDxy
+LmQubGVuZ3RoOysrdCl7cz1yLmUKaWYodD49cy5sZW5ndGgpcmV0dXJuIEguT0gocyx0KQpzPXErSC5F
+aihzW3RdKQpxPXIuZAppZih0Pj1xLmxlbmd0aClyZXR1cm4gSC5PSChxLHQpCnE9cytILkVqKHFbdF0p
+fXErPUguRWooQy5ObS5nclooci5lKSkKcmV0dXJuIHEuY2hhckNvZGVBdCgwKT09MD9xOnF9LApzbko6
+ZnVuY3Rpb24oYSl7dGhpcy5kPXUuZUcuYShhKX0sCnNQaDpmdW5jdGlvbihhKXt0aGlzLmU9dS5lRy5h
+KGEpfX0KWC5xUi5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLmEuZ21JKCl9
+LAokUzo0OX0KWC5kdi5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJQYXRoRXhjZXB0aW9u
+OiAiK3RoaXMuYX19Ck8uekwucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5nb2Mo
+dGhpcyl9fQpFLk9GLnByb3RvdHlwZT17ClVkOmZ1bmN0aW9uKGEpe3JldHVybiBDLnhCLnRnKGEsIi8i
+KX0sCnI0OmZ1bmN0aW9uKGEpe3JldHVybiBhPT09NDd9LApkczpmdW5jdGlvbihhKXt2YXIgdD1hLmxl
+bmd0aApyZXR1cm4gdCE9PTAmJkMueEIubShhLHQtMSkhPT00N30sClNwOmZ1bmN0aW9uKGEsYil7aWYo
+YS5sZW5ndGghPT0wJiZDLnhCLlcoYSwwKT09PTQ3KXJldHVybiAxCnJldHVybiAwfSwKWXI6ZnVuY3Rp
+b24oYSl7cmV0dXJuIHRoaXMuU3AoYSwhMSl9LApoSzpmdW5jdGlvbihhKXtyZXR1cm4hMX0sCmdvYzpm
+dW5jdGlvbigpe3JldHVybiJwb3NpeCJ9LApnbUk6ZnVuY3Rpb24oKXtyZXR1cm4iLyJ9fQpGLnJ1LnBy
+b3RvdHlwZT17ClVkOmZ1bmN0aW9uKGEpe3JldHVybiBDLnhCLnRnKGEsIi8iKX0sCnI0OmZ1bmN0aW9u
+KGEpe3JldHVybiBhPT09NDd9LApkczpmdW5jdGlvbihhKXt2YXIgdD1hLmxlbmd0aAppZih0PT09MCly
+ZXR1cm4hMQppZihDLnhCLm0oYSx0LTEpIT09NDcpcmV0dXJuITAKcmV0dXJuIEMueEIuVGMoYSwiOi8v
+IikmJnRoaXMuWXIoYSk9PT10fSwKU3A6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwPWEubGVuZ3Ro
+CmlmKHA9PT0wKXJldHVybiAwCmlmKEMueEIuVyhhLDApPT09NDcpcmV0dXJuIDEKZm9yKHQ9MDt0PHA7
+Kyt0KXtzPUMueEIuVyhhLHQpCmlmKHM9PT00NylyZXR1cm4gMAppZihzPT09NTgpe2lmKHQ9PT0wKXJl
+dHVybiAwCnI9Qy54Qi5YVShhLCIvIixDLnhCLlFpKGEsIi8vIix0KzEpP3QrMzp0KQppZihyPD0wKXJl
+dHVybiBwCmlmKCFifHxwPHIrMylyZXR1cm4gcgppZighQy54Qi5uKGEsImZpbGU6Ly8iKSlyZXR1cm4g
+cgppZighQi5ZdShhLHIrMSkpcmV0dXJuIHIKcT1yKzMKcmV0dXJuIHA9PT1xP3E6cis0fX1yZXR1cm4g
+MH0sCllyOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLlNwKGEsITEpfSwKaEs6ZnVuY3Rpb24oYSl7cmV0
+dXJuIGEubGVuZ3RoIT09MCYmQy54Qi5XKGEsMCk9PT00N30sCmdvYzpmdW5jdGlvbigpe3JldHVybiJ1
+cmwifSwKZ21JOmZ1bmN0aW9uKCl7cmV0dXJuIi8ifX0KTC5JVi5wcm90b3R5cGU9ewpVZDpmdW5jdGlv
+bihhKXtyZXR1cm4gQy54Qi50ZyhhLCIvIil9LApyNDpmdW5jdGlvbihhKXtyZXR1cm4gYT09PTQ3fHxh
+PT09OTJ9LApkczpmdW5jdGlvbihhKXt2YXIgdD1hLmxlbmd0aAppZih0PT09MClyZXR1cm4hMQp0PUMu
+eEIubShhLHQtMSkKcmV0dXJuISh0PT09NDd8fHQ9PT05Mil9LApTcDpmdW5jdGlvbihhLGIpe3ZhciB0
+LHMscj1hLmxlbmd0aAppZihyPT09MClyZXR1cm4gMAp0PUMueEIuVyhhLDApCmlmKHQ9PT00NylyZXR1
+cm4gMQppZih0PT09OTIpe2lmKHI8Mnx8Qy54Qi5XKGEsMSkhPT05MilyZXR1cm4gMQpzPUMueEIuWFUo
+YSwiXFwiLDIpCmlmKHM+MCl7cz1DLnhCLlhVKGEsIlxcIixzKzEpCmlmKHM+MClyZXR1cm4gc31yZXR1
+cm4gcn1pZihyPDMpcmV0dXJuIDAKaWYoIUIuT1ModCkpcmV0dXJuIDAKaWYoQy54Qi5XKGEsMSkhPT01
+OClyZXR1cm4gMApyPUMueEIuVyhhLDIpCmlmKCEocj09PTQ3fHxyPT09OTIpKXJldHVybiAwCnJldHVy
+biAzfSwKWXI6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuU3AoYSwhMSl9LApoSzpmdW5jdGlvbihhKXty
+ZXR1cm4gdGhpcy5ZcihhKT09PTF9LApPdDpmdW5jdGlvbihhLGIpe3ZhciB0CmlmKGE9PT1iKXJldHVy
+biEwCmlmKGE9PT00NylyZXR1cm4gYj09PTkyCmlmKGE9PT05MilyZXR1cm4gYj09PTQ3CmlmKChhXmIp
+IT09MzIpcmV0dXJuITEKdD1hfDMyCnJldHVybiB0Pj05NyYmdDw9MTIyfSwKTmM6ZnVuY3Rpb24oYSxi
+KXt2YXIgdCxzLHIKaWYoYT09YilyZXR1cm4hMAp0PWEubGVuZ3RoCmlmKHQhPT1iLmxlbmd0aClyZXR1
+cm4hMQpmb3Iocz1KLnJZKGIpLHI9MDtyPHQ7KytyKWlmKCF0aGlzLk90KEMueEIuVyhhLHIpLHMuVyhi
+LHIpKSlyZXR1cm4hMQpyZXR1cm4hMH0sCmdvYzpmdW5jdGlvbigpe3JldHVybiJ3aW5kb3dzIn0sCmdt
+STpmdW5jdGlvbigpe3JldHVybiJcXCJ9fTsoZnVuY3Rpb24gYWxpYXNlcygpe3ZhciB0PUoudkIucHJv
+dG90eXBlCnQuVT10LncKdC5Taj10LmU3CnQ9Si5NRi5wcm90b3R5cGUKdC50PXQudwp0PVAuY1gucHJv
+dG90eXBlCnQuR0c9dC5ldgp0PVAuTWgucHJvdG90eXBlCnQueGI9dC53CnQ9Vy5jdi5wcm90b3R5cGUK
+dC5EVz10LnI2CnQ9Vy5tNi5wcm90b3R5cGUKdC5qRj10LkViCnQ9UC5FNC5wcm90b3R5cGUKdC5Vcj10
+LnEKdC5lND10Lll9KSgpOyhmdW5jdGlvbiBpbnN0YWxsVGVhck9mZnMoKXt2YXIgdD1odW5rSGVscGVy
+cy5fc3RhdGljXzEscz1odW5rSGVscGVycy5fc3RhdGljXzAscj1odW5rSGVscGVycy5pbnN0YWxsSW5z
+dGFuY2VUZWFyT2ZmLHE9aHVua0hlbHBlcnMuaW5zdGFsbFN0YXRpY1RlYXJPZmYscD1odW5rSGVscGVy
+cy5faW5zdGFuY2VfMXUKdChQLCJFWCIsIlpWIiw5KQp0KFAsInl0Iiwib0EiLDkpCnQoUCwicVciLCJC
+eiIsOSkKcyhQLCJWOSIsImVOIiwxKQpyKFAuUGYucHJvdG90eXBlLCJnWUoiLDAsMSxudWxsLFsiJDIi
+LCIkMSJdLFsidzAiLCJwbSJdLDM0LDApCnQoUCwiUEgiLCJNdCIsNikKcShXLCJwUyIsNCxudWxsLFsi
+JDQiXSxbInlXIl0sMTAsMCkKcShXLCJWNCIsNCxudWxsLFsiJDQiXSxbIlFXIl0sMTAsMCkKcChQLkFz
+LnByb3RvdHlwZSwiZ3VNIiwiVCIsNikKdChQLCJpRyIsIndZIiw1MikKdChQLCJ3MCIsIkw3IiwzNSkK
+dChMLCJpUyIsImk2IiwxNyl9KSgpOyhmdW5jdGlvbiBpbmhlcml0YW5jZSgpe3ZhciB0PWh1bmtIZWxw
+ZXJzLm1peGluLHM9aHVua0hlbHBlcnMuaW5oZXJpdCxyPWh1bmtIZWxwZXJzLmluaGVyaXRNYW55CnMo
+UC5NaCxudWxsKQpyKFAuTWgsW0guRkssSi52QixKLm0xLFAuWFMsUC5uWSxQLmNYLEguYTcsUC5BbixI
+LlNVLEguUmUsSC53dixQLlBuLEguV1UsSC5MSSxILnYsSC5mOSxILmJxLEguWE8sUC5ZayxILmRiLEgu
+TjYsSC5WUixILkVLLEguUGIsSC50USxILlNkLEguSmMsSC5HLFAuVzMsUC5paCxQLkZ5LFAuR1YsUC5i
+OCxQLlBmLFAuRmUsUC52cyxQLk9NLFAucWgsUC5NTyxQLmtULFAueEksUC5DdyxQLm0wLFAuWHYsUC5i
+bixQLmxtLFAubEQsUC5LUCxQLk1hLFAuV1ksUC5VayxQLlJ3LFAuYnosUC5hMixQLmlQLFAubGYsUC5r
+NSxQLktZLFAuQ0QsUC5hRSxQLkVILFAuek0sUC5aMCxQLk4zLFAuYzgsUC5PZCxQLmliLFAuR3osUC5a
+ZCxQLnFVLFAuUm4sUC5HRCxQLkRuLFAuUEUsUC5VZixXLmlkLFcuRmssVy5KUSxXLkdtLFcudkQsVy5t
+NixXLk93LFcuVzksVy5kVyxXLkZiLFcua0YsVy5tayxXLktvLFAuaUosUC5FNCxQLm42LFUuZDIsVS5T
+ZSxVLk1sLFUueUQsVS53YixCLmo4LEIucXAsVC5tUSxMLlhBLEwuWlosTC5POSxNLmxJLE8uekwsWC5X
+RCxYLmR2XSkKcihKLnZCLFtKLnlFLEoud2UsSi5NRixKLmpkLEoucUksSi5EcixILkVULFcuRDAsVy5B
+eixXLkxlLFcuTmgsVy5hZSxXLklCLFcubjcsVy5lYSxXLmJyLFcuU2csVy51OCxXLks3LFcuWFcsUC5o
+Rl0pCnIoSi5NRixbSi5pQyxKLmtkLEouYzVdKQpzKEouUG8sSi5qZCkKcihKLnFJLFtKLnVyLEouVkFd
+KQpyKFAuWFMsW0gubmQsSC5XMCxILmF6LEgudlYsSC5FcSxQLkM2LEgudTksUC5uLFAudSxQLm1wLFAu
+dWIsUC5kcyxQLmxqLFAuVVYsUC5jXSkKcyhQLkxVLFAublkpCnIoUC5MVSxbSC53MixXLnd6LFcuZTdd
+KQpzKEgucWosSC53MikKcihQLmNYLFtILmJRLEguaTEsSC5VNSxILlhSLFAubVcsSC51bl0pCnIoSC5i
+USxbSC5hTCxILmk1LFAueHVdKQpyKEguYUwsW0gubkgsSC5sSixQLmk4XSkKcyhILnh5LEguaTEpCnIo
+UC5BbixbSC5NSCxILlNPXSkKcyhQLlJVLFAuUG4pCnMoUC5HaixQLlJVKQpzKEguUEQsUC5HaikKcyhI
+LkxQLEguV1UpCnIoSC52LFtILkNqLEguQW0sSC5sYyxILmRDLEgud04sSC5WWCxQLnRoLFAuaGEsUC5W
+cyxQLkZ0LFAueUgsUC5XTSxQLlNYLFAuR3MsUC5kYSxQLm9RLFAucFYsUC5VNyxQLnZyLFAucnQsUC5L
+RixQLlpMLFAuUlQsUC5qWixQLnJxLFAuUlcsUC5CNSxQLnVPLFAucEssUC5oaixQLlZwLFAuT1IsUC5y
+YSxQLnlRLFAucGcsUC5XRixQLm4xLFAuY1MsUC5WQyxQLkpULFAuUlosUC5NRSxQLnk1LFAucTMsUC55
+SSxQLmM2LFAucWQsVy5DdixXLmJVLFcuaEgsVy5LUyxXLkEzLFcudk4sVy5VdixXLkVnLFcuRW8sVy5X
+ayxXLklBLFcuZm0sUC5qZyxQLlRhLFAuR0UsUC5ONyxQLnVRLFAuUEMsUC5tdCxQLk56LFAuUVMsUC5u
+cCxMLmUsTC5WVyxMLm9aLEwuanIsTC5xbCxMLkhpLEwuQlQsTC5QWSxMLkwsTC5XeCxMLkFPLEwuZE4s
+TC5IbyxMLnh6LEwuSUMsTC5MMSxMLm5ULEwuTlksTC5lWCxMLkRULEwuZUgsTC55dSxMLnpELEwuVFcs
+TC54cixMLkVFLEwuUUwsTC5WUyxMLlRELE0uTWksTS5xNyxNLk5vLFgucVJdKQpyKEgubGMsW0guengs
+SC5yVF0pCnMoSC5rWSxQLkM2KQpzKFAuaWwsUC5ZaykKcihQLmlsLFtILk41LFAudXcsVy5jZixXLlN5
+XSkKcihQLm1XLFtILktXLFAucTRdKQpzKEguYjAsSC5FVCkKcihILmIwLFtILlJHLEguV0JdKQpzKEgu
+VlAsSC5SRykKcyhILkRnLEguVlApCnMoSC5aRyxILldCKQpzKEguUGcsSC5aRykKcihILlBnLFtILnhq
+LEguZEUsSC5aQSxILmRULEguUHEsSC5lRSxILlY2XSkKcyhILmlNLEgudTkpCnMoUC5aZixQLlBmKQpz
+KFAuSmksUC5tMCkKcyhQLmI2LFAuWHYpCnMoUC5WaixQLldZKQpyKFAuVWssW1AuQ1YsUC5aaSxQLmJ5
+XSkKcyhQLndJLFAua1QpCnIoUC53SSxbUC5VOCxQLk14LFAuRTMsUC5HWV0pCnMoUC51NSxQLlppKQpy
+KFAubGYsW1AuQ1AsUC5JZl0pCnIoUC51LFtQLmJKLFAuZVldKQpzKFAucWUsUC5EbikKcihXLkQwLFtX
+LnVILFcud2EsVy5LNSxXLkNtXSkKcihXLnVILFtXLmN2LFcubngsVy5RRixXLkNRXSkKcihXLmN2LFtX
+LnFFLFAuZDVdKQpyKFcucUUsW1cuR2gsVy5mWSxXLm5CLFcuUVAsVy5oNCxXLlNOLFcubHAsVy5UYixX
+Lkl2LFcuV1AsVy55WV0pCnMoVy5vSixXLkxlKQpzKFcuVDUsVy5BeikKcyhXLlZiLFcuUUYpCnMoVy5m
+SixXLndhKQpyKFcuZWEsW1cudzYsVy5ld10pCnMoVy5PSyxXLnc2KQpzKFcuckIsVy5LNykKcyhXLkJI
+LFcuckIpCnMoVy53NCxXLklCKQpzKFcub2EsVy5YVykKcyhXLnJoLFcub2EpCnMoVy5pNyxXLmNmKQpz
+KFAuQXMsUC5WaikKcihQLkFzLFtXLkk0LFAuS2VdKQpzKFcuUk8sUC5xaCkKcyhXLmV1LFcuUk8pCnMo
+Vy54QyxQLk1PKQpzKFcuY3QsVy5tNikKcyhQLkJmLFAuaUopCnIoUC5FNCxbUC5yNyxQLmNvXSkKcyhQ
+LlR6LFAuY28pCnMoUC5iQixQLmQ1KQpzKEIuZnYsTy56TCkKcihCLmZ2LFtFLk9GLEYucnUsTC5JVl0p
+CnQoSC53MixILlJlKQp0KEguUkcsUC5sRCkKdChILlZQLEguU1UpCnQoSC5XQixQLmxEKQp0KEguWkcs
+SC5TVSkKdChQLm5ZLFAubEQpCnQoUC5XWSxQLk1hKQp0KFAuUlUsUC5LUCkKdChXLkxlLFcuaWQpCnQo
+Vy5LNyxQLmxEKQp0KFcuckIsVy5HbSkKdChXLlhXLFAubEQpCnQoVy5vYSxXLkdtKQp0KFAuY28sUC5s
+RCl9KSgpCnZhciB2PXt0eXBlVW5pdmVyc2U6e2VDOm5ldyBNYXAoKSx0Ujp7fSxlVDp7fSx0UFY6e30s
+c0VBOltdfSxtYW5nbGVkR2xvYmFsTmFtZXM6e0lmOiJpbnQiLENQOiJkb3VibGUiLGxmOiJudW0iLHFV
+OiJTdHJpbmciLGEyOiJib29sIixjODoiTnVsbCIsek06Ikxpc3QifSxtYW5nbGVkTmFtZXM6e30sZ2V0
+VHlwZUZyb21OYW1lOmdldEdsb2JhbEZyb21OYW1lLG1ldGFkYXRhOltdLHR5cGVzOlsiYzgoKSIsIn4o
+KSIsImM4KEAsQCkiLCJjOChPSyopIiwiYzgoY3YqKSIsIkAoQCkiLCJxVShxVSkiLCJjOChxVSxxVSki
+LCJjOChmSiopIiwifih+KCkpIiwiYTIoY3YscVUscVUsSlEpIiwiYzgoQCkiLCJjOChxVSxAKSIsImEy
+KGtGKSIsImEyKHFVKSIsIn4oeHU8cVU+KSIsImM4KGVhKikiLCJ+KE9LKikiLCJhMioocVUqKSIsIlow
+PHFVLHFVPihaMDxxVSxxVT4scVUpIiwiSWYoSWYsSWYpIiwiQChALHFVKSIsIn4ocVUscVU/KSIsIm42
+KElmKSIsIm42KEAsQCkiLCJhMih1SCkiLCJjOChALEd6KSIsImM4KGV3KSIsIkAoZWEpIiwifihAKSIs
+ImM4KH4oKSkiLCJ+KHVILHVIPykiLCJjOChJZixAKSIsImEyKHh1PHFVPikiLCJ+KE1oW0d6P10pIiwi
+TWg/KEApIiwiVHo8QD4oQCkiLCJFNChAKSIsImM4KE1oLEd6KSIsInZzPEA+KEApIiwiYzgoWjA8cVUq
+LE1oKj4qKSIsImI4PGM4PiooT0sqKSIsInFVKihPSyopIiwiYzgoTWg/LE1oPykiLCJjOChldyopIiwi
+QCgpIiwiYzgoR0QsQCkiLCJAKHFVKSIsInFVKihxVSopIiwicVUqKElmKikiLCJ+KHFVLElmKSIsIn4o
+cVVbQF0pIiwiTWg/KE1oPykiLCJyNyhAKSJdLGludGVyY2VwdG9yc0J5VGFnOm51bGwsbGVhZlRhZ3M6
+bnVsbCxhcnJheVJ0aTp0eXBlb2YgU3ltYm9sPT0iZnVuY3Rpb24iJiZ0eXBlb2YgU3ltYm9sKCk9PSJz
+eW1ib2wiP1N5bWJvbCgiJHRpIik6IiR0aSJ9CkgueGIodi50eXBlVW5pdmVyc2UsSlNPTi5wYXJzZSgn
+eyJjNSI6Ik1GIiwiaUMiOiJNRiIsImtkIjoiTUYiLCJyeCI6ImVhIiwiZTUiOiJlYSIsIlkwIjoiZDUi
+LCJ0cCI6ImQ1IiwiRzgiOiJldyIsIk1yIjoicUUiLCJlTCI6InFFIiwiSTAiOiJ1SCIsImhzIjoidUgi
+LCJYZyI6IlFGIiwieWMiOiJPSyIsInk0IjoidzYiLCJhUCI6IkNtIiwieGMiOiJueCIsImtKIjoibngi
+LCJ6VSI6IkRnIiwiZGYiOiJFVCIsInlFIjp7ImEyIjpbXX0sIndlIjp7ImM4IjpbXX0sIk1GIjp7InZt
+IjpbXSwiRUgiOltdfSwiamQiOnsiek0iOlsiMSJdLCJiUSI6WyIxIl0sImNYIjpbIjEiXX0sIlBvIjp7
+ImpkIjpbIjEiXSwiek0iOlsiMSJdLCJiUSI6WyIxIl0sImNYIjpbIjEiXX0sIm0xIjp7IkFuIjpbIjEi
+XX0sInFJIjp7IkNQIjpbXSwibGYiOltdfSwidXIiOnsiSWYiOltdLCJDUCI6W10sImxmIjpbXX0sIlZB
+Ijp7IkNQIjpbXSwibGYiOltdfSwiRHIiOnsicVUiOltdLCJ2WCI6W119LCJuZCI6eyJYUyI6W119LCJx
+aiI6eyJSZSI6WyJJZiJdLCJsRCI6WyJJZiJdLCJ6TSI6WyJJZiJdLCJiUSI6WyJJZiJdLCJjWCI6WyJJ
+ZiJdLCJsRC5FIjoiSWYiLCJSZS5FIjoiSWYifSwiYlEiOnsiY1giOlsiMSJdfSwiYUwiOnsiYlEiOlsi
+MSJdLCJjWCI6WyIxIl19LCJuSCI6eyJhTCI6WyIxIl0sImJRIjpbIjEiXSwiY1giOlsiMSJdLCJhTC5F
+IjoiMSIsImNYLkUiOiIxIn0sImE3Ijp7IkFuIjpbIjEiXX0sImkxIjp7ImNYIjpbIjIiXSwiY1guRSI6
+IjIifSwieHkiOnsiaTEiOlsiMSIsIjIiXSwiYlEiOlsiMiJdLCJjWCI6WyIyIl0sImNYLkUiOiIyIn0s
+Ik1IIjp7IkFuIjpbIjIiXX0sImxKIjp7ImFMIjpbIjIiXSwiYlEiOlsiMiJdLCJjWCI6WyIyIl0sImFM
+LkUiOiIyIiwiY1guRSI6IjIifSwiVTUiOnsiY1giOlsiMSJdLCJjWC5FIjoiMSJ9LCJTTyI6eyJBbiI6
+WyIxIl19LCJ3MiI6eyJSZSI6WyIxIl0sImxEIjpbIjEiXSwiek0iOlsiMSJdLCJiUSI6WyIxIl0sImNY
+IjpbIjEiXX0sInd2Ijp7IkdEIjpbXX0sIlBEIjp7IkdqIjpbIjEiLCIyIl0sIlJVIjpbIjEiLCIyIl0s
+IlBuIjpbIjEiLCIyIl0sIktQIjpbIjEiLCIyIl0sIlowIjpbIjEiLCIyIl19LCJXVSI6eyJaMCI6WyIx
+IiwiMiJdfSwiTFAiOnsiV1UiOlsiMSIsIjIiXSwiWjAiOlsiMSIsIjIiXX0sIlhSIjp7ImNYIjpbIjEi
+XSwiY1guRSI6IjEifSwiTEkiOnsidlEiOltdfSwiVzAiOnsiWFMiOltdfSwiYXoiOnsiWFMiOltdfSwi
+dlYiOnsiWFMiOltdfSwiWE8iOnsiR3oiOltdfSwidiI6eyJFSCI6W119LCJsYyI6eyJFSCI6W119LCJ6
+eCI6eyJFSCI6W119LCJyVCI6eyJFSCI6W119LCJFcSI6eyJYUyI6W119LCJrWSI6eyJYUyI6W119LCJO
+NSI6eyJGbyI6WyIxIiwiMiJdLCJZayI6WyIxIiwiMiJdLCJaMCI6WyIxIiwiMiJdLCJZay5LIjoiMSIs
+IllrLlYiOiIyIn0sImk1Ijp7ImJRIjpbIjEiXSwiY1giOlsiMSJdLCJjWC5FIjoiMSJ9LCJONiI6eyJB
+biI6WyIxIl19LCJWUiI6eyJ3TCI6W10sInZYIjpbXX0sIkVLIjp7ImliIjpbXSwiT2QiOltdfSwiS1ci
+OnsiY1giOlsiaWIiXSwiY1guRSI6ImliIn0sIlBiIjp7IkFuIjpbImliIl19LCJ0USI6eyJPZCI6W119
+LCJ1biI6eyJjWCI6WyJPZCJdLCJjWC5FIjoiT2QifSwiU2QiOnsiQW4iOlsiT2QiXX0sIkVUIjp7IkFT
+IjpbXX0sImIwIjp7IlhqIjpbIjEiXSwiRVQiOltdLCJBUyI6W119LCJEZyI6eyJsRCI6WyJDUCJdLCJY
+aiI6WyJDUCJdLCJ6TSI6WyJDUCJdLCJFVCI6W10sImJRIjpbIkNQIl0sIlNVIjpbIkNQIl0sIkFTIjpb
+XSwiY1giOlsiQ1AiXSwibEQuRSI6IkNQIn0sIlBnIjp7ImxEIjpbIklmIl0sInpNIjpbIklmIl0sIlhq
+IjpbIklmIl0sIkVUIjpbXSwiYlEiOlsiSWYiXSwiU1UiOlsiSWYiXSwiQVMiOltdLCJjWCI6WyJJZiJd
+fSwieGoiOnsibEQiOlsiSWYiXSwiek0iOlsiSWYiXSwiWGoiOlsiSWYiXSwiRVQiOltdLCJiUSI6WyJJ
+ZiJdLCJTVSI6WyJJZiJdLCJBUyI6W10sImNYIjpbIklmIl0sImxELkUiOiJJZiJ9LCJkRSI6eyJsRCI6
+WyJJZiJdLCJ6TSI6WyJJZiJdLCJYaiI6WyJJZiJdLCJFVCI6W10sImJRIjpbIklmIl0sIlNVIjpbIklm
+Il0sIkFTIjpbXSwiY1giOlsiSWYiXSwibEQuRSI6IklmIn0sIlpBIjp7ImxEIjpbIklmIl0sInpNIjpb
+IklmIl0sIlhqIjpbIklmIl0sIkVUIjpbXSwiYlEiOlsiSWYiXSwiU1UiOlsiSWYiXSwiQVMiOltdLCJj
+WCI6WyJJZiJdLCJsRC5FIjoiSWYifSwiZFQiOnsibEQiOlsiSWYiXSwiek0iOlsiSWYiXSwiWGoiOlsi
+SWYiXSwiRVQiOltdLCJiUSI6WyJJZiJdLCJTVSI6WyJJZiJdLCJBUyI6W10sImNYIjpbIklmIl0sImxE
+LkUiOiJJZiJ9LCJQcSI6eyJsRCI6WyJJZiJdLCJ6TSI6WyJJZiJdLCJYaiI6WyJJZiJdLCJFVCI6W10s
+ImJRIjpbIklmIl0sIlNVIjpbIklmIl0sIkFTIjpbXSwiY1giOlsiSWYiXSwibEQuRSI6IklmIn0sImVF
+Ijp7ImxEIjpbIklmIl0sInpNIjpbIklmIl0sIlhqIjpbIklmIl0sIkVUIjpbXSwiYlEiOlsiSWYiXSwi
+U1UiOlsiSWYiXSwiQVMiOltdLCJjWCI6WyJJZiJdLCJsRC5FIjoiSWYifSwiVjYiOnsibjYiOltdLCJs
+RCI6WyJJZiJdLCJ6TSI6WyJJZiJdLCJYaiI6WyJJZiJdLCJFVCI6W10sImJRIjpbIklmIl0sIlNVIjpb
+IklmIl0sIkFTIjpbXSwiY1giOlsiSWYiXSwibEQuRSI6IklmIn0sInU5Ijp7IlhTIjpbXX0sImlNIjp7
+IlhTIjpbXX0sIkdWIjp7IkFuIjpbIjEiXX0sInE0Ijp7ImNYIjpbIjEiXSwiY1guRSI6IjEifSwiWmYi
+OnsiUGYiOlsiMSJdfSwidnMiOnsiYjgiOlsiMSJdfSwiQ3ciOnsiWFMiOltdfSwibTAiOnsiSkIiOltd
+fSwiSmkiOnsibTAiOltdLCJKQiI6W119LCJiNiI6eyJYdiI6WyIxIl0sInh1IjpbIjEiXSwiYlEiOlsi
+MSJdLCJjWCI6WyIxIl19LCJsbSI6eyJBbiI6WyIxIl19LCJtVyI6eyJjWCI6WyIxIl19LCJMVSI6eyJs
+RCI6WyIxIl0sInpNIjpbIjEiXSwiYlEiOlsiMSJdLCJjWCI6WyIxIl19LCJpbCI6eyJZayI6WyIxIiwi
+MiJdLCJaMCI6WyIxIiwiMiJdfSwiWWsiOnsiWjAiOlsiMSIsIjIiXX0sIlBuIjp7IlowIjpbIjEiLCIy
+Il19LCJHaiI6eyJSVSI6WyIxIiwiMiJdLCJQbiI6WyIxIiwiMiJdLCJLUCI6WyIxIiwiMiJdLCJaMCI6
+WyIxIiwiMiJdfSwiVmoiOnsiTWEiOlsiMSJdLCJ4dSI6WyIxIl0sImJRIjpbIjEiXSwiY1giOlsiMSJd
+fSwiWHYiOnsieHUiOlsiMSJdLCJiUSI6WyIxIl0sImNYIjpbIjEiXX0sInV3Ijp7IllrIjpbInFVIiwi
+QCJdLCJaMCI6WyJxVSIsIkAiXSwiWWsuSyI6InFVIiwiWWsuViI6IkAifSwiaTgiOnsiYUwiOlsicVUi
+XSwiYlEiOlsicVUiXSwiY1giOlsicVUiXSwiYUwuRSI6InFVIiwiY1guRSI6InFVIn0sIkNWIjp7IlVr
+IjpbInpNPElmPiIsInFVIl0sIlVrLlMiOiJ6TTxJZj4ifSwiVTgiOnsid0kiOlsiek08SWY+IiwicVUi
+XX0sIlppIjp7IlVrIjpbInFVIiwiek08SWY+Il19LCJieSI6eyJVayI6WyJNaD8iLCJxVSJdLCJVay5T
+IjoiTWg/In0sIk14Ijp7IndJIjpbInFVIiwiTWg/Il19LCJ1NSI6eyJVayI6WyJxVSIsInpNPElmPiJd
+LCJVay5TIjoicVUifSwiRTMiOnsid0kiOlsicVUiLCJ6TTxJZj4iXX0sIkdZIjp7IndJIjpbInpNPElm
+PiIsInFVIl19LCJDUCI6eyJsZiI6W119LCJDNiI6eyJYUyI6W119LCJuIjp7IlhTIjpbXX0sInUiOnsi
+WFMiOltdfSwiYkoiOnsiWFMiOltdfSwiZVkiOnsiWFMiOltdfSwibXAiOnsiWFMiOltdfSwidWIiOnsi
+WFMiOltdfSwiZHMiOnsiWFMiOltdfSwibGoiOnsiWFMiOltdfSwiVVYiOnsiWFMiOltdfSwiazUiOnsi
+WFMiOltdfSwiS1kiOnsiWFMiOltdfSwiYyI6eyJYUyI6W119LCJJZiI6eyJsZiI6W119LCJ6TSI6eyJi
+USI6WyIxIl0sImNYIjpbIjEiXX0sImliIjp7Ik9kIjpbXX0sInh1Ijp7ImJRIjpbIjEiXSwiY1giOlsi
+MSJdfSwiWmQiOnsiR3oiOltdfSwicVUiOnsidlgiOltdfSwiUm4iOnsiQkwiOltdfSwiRG4iOnsiaUQi
+OltdfSwiVWYiOnsiaUQiOltdfSwicWUiOnsiaUQiOltdfSwicUUiOnsiY3YiOltdLCJ1SCI6W10sIkQw
+IjpbXX0sIkdoIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJmWSI6eyJjdiI6W10sInVIIjpbXSwi
+RDAiOltdfSwibkIiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIlFQIjp7ImN2IjpbXSwidUgiOltd
+LCJEMCI6W119LCJueCI6eyJ1SCI6W10sIkQwIjpbXX0sIlFGIjp7InVIIjpbXSwiRDAiOltdfSwiSUIi
+OnsidG4iOlsibGYiXX0sInd6Ijp7ImxEIjpbIjEiXSwiek0iOlsiMSJdLCJiUSI6WyIxIl0sImNYIjpb
+IjEiXSwibEQuRSI6IjEifSwiY3YiOnsidUgiOltdLCJEMCI6W119LCJUNSI6eyJBeiI6W119LCJoNCI6
+eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiVmIiOnsidUgiOltdLCJEMCI6W119LCJmSiI6eyJEMCI6
+W119LCJ3YSI6eyJEMCI6W119LCJPSyI6eyJlYSI6W119LCJlNyI6eyJsRCI6WyJ1SCJdLCJ6TSI6WyJ1
+SCJdLCJiUSI6WyJ1SCJdLCJjWCI6WyJ1SCJdLCJsRC5FIjoidUgifSwidUgiOnsiRDAiOltdfSwiQkgi
+OnsiR20iOlsidUgiXSwibEQiOlsidUgiXSwiek0iOlsidUgiXSwiWGoiOlsidUgiXSwiYlEiOlsidUgi
+XSwiY1giOlsidUgiXSwiR20uRSI6InVIIiwibEQuRSI6InVIIn0sIlNOIjp7ImN2IjpbXSwidUgiOltd
+LCJEMCI6W119LCJldyI6eyJlYSI6W119LCJscCI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiVGIi
+OnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIkl2Ijp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJX
+UCI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwieVkiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0s
+Inc2Ijp7ImVhIjpbXX0sIks1Ijp7InY2IjpbXSwiRDAiOltdfSwiQ20iOnsiRDAiOltdfSwiQ1EiOnsi
+dUgiOltdLCJEMCI6W119LCJ3NCI6eyJ0biI6WyJsZiJdfSwicmgiOnsiR20iOlsidUgiXSwibEQiOlsi
+dUgiXSwiek0iOlsidUgiXSwiWGoiOlsidUgiXSwiYlEiOlsidUgiXSwiY1giOlsidUgiXSwiR20uRSI6
+InVIIiwibEQuRSI6InVIIn0sImNmIjp7IllrIjpbInFVIiwicVUiXSwiWjAiOlsicVUiLCJxVSJdfSwi
+aTciOnsiWWsiOlsicVUiLCJxVSJdLCJaMCI6WyJxVSIsInFVIl0sIllrLksiOiJxVSIsIllrLlYiOiJx
+VSJ9LCJTeSI6eyJZayI6WyJxVSIsInFVIl0sIlowIjpbInFVIiwicVUiXSwiWWsuSyI6InFVIiwiWWsu
+ViI6InFVIn0sIkk0Ijp7Ik1hIjpbInFVIl0sInh1IjpbInFVIl0sImJRIjpbInFVIl0sImNYIjpbInFV
+Il19LCJSTyI6eyJxaCI6WyIxIl19LCJldSI6eyJSTyI6WyIxIl0sInFoIjpbIjEiXX0sInhDIjp7Ik1P
+IjpbIjEiXX0sIkpRIjp7ImtGIjpbXX0sInZEIjp7ImtGIjpbXX0sIm02Ijp7ImtGIjpbXX0sImN0Ijp7
+ImtGIjpbXX0sIk93Ijp7ImtGIjpbXX0sIlc5Ijp7IkFuIjpbIjEiXX0sImRXIjp7InY2IjpbXSwiRDAi
+OltdfSwibWsiOnsieTAiOltdfSwiS28iOnsib24iOltdfSwiQXMiOnsiTWEiOlsicVUiXSwieHUiOlsi
+cVUiXSwiYlEiOlsicVUiXSwiY1giOlsicVUiXX0sInI3Ijp7IkU0IjpbXX0sIlR6Ijp7ImxEIjpbIjEi
+XSwiek0iOlsiMSJdLCJiUSI6WyIxIl0sIkU0IjpbXSwiY1giOlsiMSJdLCJsRC5FIjoiMSJ9LCJiQiI6
+eyJkNSI6W10sImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJLZSI6eyJNYSI6WyJxVSJdLCJ4dSI6WyJx
+VSJdLCJiUSI6WyJxVSJdLCJjWCI6WyJxVSJdfSwiZDUiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0s
+Im42Ijp7InpNIjpbIklmIl0sImJRIjpbIklmIl0sIkFTIjpbXSwiY1giOlsiSWYiXX0sIlhBIjp7ImtG
+IjpbXX0sIk9GIjp7ImZ2IjpbXX0sInJ1Ijp7ImZ2IjpbXX0sIklWIjp7ImZ2IjpbXX19JykpCkguRkYo
+di50eXBlVW5pdmVyc2UsSlNPTi5wYXJzZSgneyJiUSI6MSwidzIiOjEsImIwIjoxLCJrVCI6MiwibVci
+OjEsIkxVIjoxLCJpbCI6MiwiVmoiOjEsIm5ZIjoxLCJXWSI6MSwiY28iOjF9JykpCnZhciB1PShmdW5j
+dGlvbiBydGlpKCl7dmFyIHQ9SC5OMApyZXR1cm57bjp0KCJDdyIpLGNSOnQoIm5CIiksdzp0KCJBeiIp
+LGs6dCgiUVAiKSxnRjp0KCJQRDxHRCxAPiIpLGd3OnQoImJRPEA+IiksaDp0KCJjdiIpLFc6dCgiWFMi
+KSxCOnQoImVhIiksYVM6dCgiRDAiKSxjODp0KCJUNSIpLFk6dCgiRUgiKSxkOnQoImI4PEA+IiksSTp0
+KCJTZyIpLG86dCgidlEiKSxlaDp0KCJjWDx1SD4iKSxROnQoImNYPHFVPiIpLG06dCgiY1g8QD4iKSxw
+OnQoImpkPGtGPiIpLHM6dCgiamQ8cVU+IiksYjp0KCJqZDxAPiIpLHQ6dCgiamQ8SWY+IiksZDc6dCgi
+amQ8U2UqPiIpLGg0OnQoImpkPGo4Kj4iKSxjUTp0KCJqZDxaWio+IiksaTp0KCJqZDxxVSo+IiksYUE6
+dCgiamQ8eUQqPiIpLGFKOnQoImpkPHdiKj4iKSxWOnQoImpkPElmKj4iKSxlSDp0KCJ2bSIpLHI6dCgi
+YzUiKSxhVTp0KCJYajxAPiIpLGFtOnQoIlR6PEA+IiksZW86dCgiTjU8R0QsQD4iKSxkejp0KCJoRiIp
+LGo6dCgiek08QD4iKSxMOnQoInpNPElmPiIpLGY6dCgiWjA8cVUscVU+Iiksdjp0KCJaMDxALEA+Iiks
+ZG86dCgibEo8cVUsQD4iKSxmajp0KCJsSjxxVSoscVU+IiksZEU6dCgiRVQiKSxibTp0KCJWNiIpLEE6
+dCgidUgiKSxlOnQoImtGIiksUDp0KCJjOCIpLEs6dCgiTWgiKSxnWjp0KCJldyIpLHE6dCgidG48bGY+
+IiksZnY6dCgid0wiKSxldzp0KCJiQiIpLEM6dCgieHU8cVU+IiksbDp0KCJHeiIpLE46dCgicVUiKSxk
+MDp0KCJxVShxVSopIiksZzc6dCgiZDUiKSxmbzp0KCJHRCIpLGFXOnQoInlZIikseDp0KCJBUyIpLGdj
+OnQoIm42IiksYWs6dCgia2QiKSxkdzp0KCJHajxxVSxxVT4iKSxkRDp0KCJpRCIpLGZpOnQoIlU1PHFV
+Kj4iKSxnNDp0KCJLNSIpLGNpOnQoInY2IiksZzI6dCgiQ20iKSxiajp0KCJaZjxmSj4iKSxiQzp0KCJa
+ZjxmSio+IiksaDk6dCgiQ1EiKSxhYzp0KCJlNyIpLEc6dCgiZXU8T0sqPiIpLFI6dCgid3o8Y3YqPiIp
+LGFvOnQoInZzPGZKPiIpLGM6dCgidnM8QD4iKSxmSjp0KCJ2czxJZj4iKSxnVjp0KCJ2czxmSio+Iiks
+Y3I6dCgiSlEiKSxKOnQoImJuIikseTp0KCJhMiIpLGFsOnQoImEyKE1oKSIpLGdmOnQoImEyKHFVKiki
+KSxnUjp0KCJDUCIpLHo6dCgiQCIpLGZPOnQoIkAoKSIpLGJJOnQoIkAoTWgpIiksYWc6dCgiQChNaCxH
+eikiKSxiVTp0KCJAKHh1PHFVPikiKSxkTzp0KCJAKHFVKSIpLGI4OnQoIkAoQCxAKSIpLFM6dCgiSWYi
+KSxkZDp0KCJHaCoiKSxnOnQoImN2KiIpLGFMOnQoImVhKiIpLEQ6dCgiZkoqIiksVDp0KCJjWDxAPioi
+KSxlUzp0KCJjWDxxVSo+KiIpLGRIOnQoIkU0KiIpLGRfOnQoInpNPGo4Kj4qIiksZUc6dCgiek08cVUq
+PioiKSxiWjp0KCJ1OCoiKSxibzp0KCJaMDxxVSosQD4qIiksYTp0KCJaMDxxVSosTWgqPioiKSxPOnQo
+Ik9LKiIpLGF3OnQoIjAmKiIpLF86dCgiTWgqIiksRTp0KCJldyoiKSxYOnQoInFVKiIpLGNoOnQoIkQw
+PyIpLGJHOnQoImI4PGM4Pj8iKSxVOnQoImNYPHFVPj8iKSxiazp0KCJ6TTxxVT4/IiksYk06dCgiek08
+QD4/IiksZWc6dCgiek08SWY+PyIpLGNaOnQoIlowPHFVLHFVPj8iKSxjOTp0KCJaMDxxVSxAPj8iKSxj
+Szp0KCJNaD8iKSxGOnQoIkZlPEAsQD4/IiksYjc6dCgiYTIoTWgpPyIpLGJ3OnQoIkAoZWEpPyIpLGZW
+OnQoIk1oPyhNaD8sTWg/KT8iKSxaOnQoIn4oKT8iKSx1OnQoIn4oZXcqKT8iKSxkaTp0KCJsZiIpLEg6
+dCgifiIpLE06dCgifigpIiksZUE6dCgifihxVSxxVSkiKSxjQTp0KCJ+KHFVLEApIil9fSkoKTsoZnVu
+Y3Rpb24gY29uc3RhbnRzKCl7dmFyIHQ9aHVua0hlbHBlcnMubWFrZUNvbnN0TGlzdApDLlJZPVcuUVAu
+cHJvdG90eXBlCkMubUg9Vy5hZS5wcm90b3R5cGUKQy5CWj1XLlZiLnByb3RvdHlwZQpDLkR0PVcuZkou
+cHJvdG90eXBlCkMuT2s9Si52Qi5wcm90b3R5cGUKQy5ObT1KLmpkLnByb3RvdHlwZQpDLmpuPUoudXIu
+cHJvdG90eXBlCkMuQ0Q9Si5xSS5wcm90b3R5cGUKQy54Qj1KLkRyLnByb3RvdHlwZQpDLkRHPUouYzUu
+cHJvdG90eXBlCkMuRXg9Vy51OC5wcm90b3R5cGUKQy5MdD1XLlNOLnByb3RvdHlwZQpDLlpRPUouaUMu
+cHJvdG90eXBlCkMuSWU9Vy5UYi5wcm90b3R5cGUKQy52Qj1KLmtkLnByb3RvdHlwZQpDLm9sPVcuSzUu
+cHJvdG90eXBlCkMueTg9bmV3IFAuVTgoKQpDLmg5PW5ldyBQLkNWKCkKQy5PND1mdW5jdGlvbiBnZXRU
+YWdGYWxsYmFjayhvKSB7CiAgdmFyIHMgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobyk7
+CiAgcmV0dXJuIHMuc3Vic3RyaW5nKDgsIHMubGVuZ3RoIC0gMSk7Cn0KQy5ZcT1mdW5jdGlvbigpIHsK
+ICB2YXIgdG9TdHJpbmdGdW5jdGlvbiA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7CiAgZnVuY3Rp
+b24gZ2V0VGFnKG8pIHsKICAgIHZhciBzID0gdG9TdHJpbmdGdW5jdGlvbi5jYWxsKG8pOwogICAgcmV0
+dXJuIHMuc3Vic3RyaW5nKDgsIHMubGVuZ3RoIC0gMSk7CiAgfQogIGZ1bmN0aW9uIGdldFVua25vd25U
+YWcob2JqZWN0LCB0YWcpIHsKICAgIGlmICgvXkhUTUxbQS1aXS4qRWxlbWVudCQvLnRlc3QodGFnKSkg
+ewogICAgICB2YXIgbmFtZSA9IHRvU3RyaW5nRnVuY3Rpb24uY2FsbChvYmplY3QpOwogICAgICBpZiAo
+bmFtZSA9PSAiW29iamVjdCBPYmplY3RdIikgcmV0dXJuIG51bGw7CiAgICAgIHJldHVybiAiSFRNTEVs
+ZW1lbnQiOwogICAgfQogIH0KICBmdW5jdGlvbiBnZXRVbmtub3duVGFnR2VuZXJpY0Jyb3dzZXIob2Jq
+ZWN0LCB0YWcpIHsKICAgIGlmIChzZWxmLkhUTUxFbGVtZW50ICYmIG9iamVjdCBpbnN0YW5jZW9mIEhU
+TUxFbGVtZW50KSByZXR1cm4gIkhUTUxFbGVtZW50IjsKICAgIHJldHVybiBnZXRVbmtub3duVGFnKG9i
+amVjdCwgdGFnKTsKICB9CiAgZnVuY3Rpb24gcHJvdG90eXBlRm9yVGFnKHRhZykgewogICAgaWYgKHR5
+cGVvZiB3aW5kb3cgPT0gInVuZGVmaW5lZCIpIHJldHVybiBudWxsOwogICAgaWYgKHR5cGVvZiB3aW5k
+b3dbdGFnXSA9PSAidW5kZWZpbmVkIikgcmV0dXJuIG51bGw7CiAgICB2YXIgY29uc3RydWN0b3IgPSB3
+aW5kb3dbdGFnXTsKICAgIGlmICh0eXBlb2YgY29uc3RydWN0b3IgIT0gImZ1bmN0aW9uIikgcmV0dXJu
+IG51bGw7CiAgICByZXR1cm4gY29uc3RydWN0b3IucHJvdG90eXBlOwogIH0KICBmdW5jdGlvbiBkaXNj
+cmltaW5hdG9yKHRhZykgeyByZXR1cm4gbnVsbDsgfQogIHZhciBpc0Jyb3dzZXIgPSB0eXBlb2YgbmF2
+aWdhdG9yID09ICJvYmplY3QiOwogIHJldHVybiB7CiAgICBnZXRUYWc6IGdldFRhZywKICAgIGdldFVu
+a25vd25UYWc6IGlzQnJvd3NlciA/IGdldFVua25vd25UYWdHZW5lcmljQnJvd3NlciA6IGdldFVua25v
+d25UYWcsCiAgICBwcm90b3R5cGVGb3JUYWc6IHByb3RvdHlwZUZvclRhZywKICAgIGRpc2NyaW1pbmF0
+b3I6IGRpc2NyaW1pbmF0b3IgfTsKfQpDLndiPWZ1bmN0aW9uKGdldFRhZ0ZhbGxiYWNrKSB7CiAgcmV0
+dXJuIGZ1bmN0aW9uKGhvb2tzKSB7CiAgICBpZiAodHlwZW9mIG5hdmlnYXRvciAhPSAib2JqZWN0Iikg
+cmV0dXJuIGhvb2tzOwogICAgdmFyIHVhID0gbmF2aWdhdG9yLnVzZXJBZ2VudDsKICAgIGlmICh1YS5p
+bmRleE9mKCJEdW1wUmVuZGVyVHJlZSIpID49IDApIHJldHVybiBob29rczsKICAgIGlmICh1YS5pbmRl
+eE9mKCJDaHJvbWUiKSA+PSAwKSB7CiAgICAgIGZ1bmN0aW9uIGNvbmZpcm0ocCkgewogICAgICAgIHJl
+dHVybiB0eXBlb2Ygd2luZG93ID09ICJvYmplY3QiICYmIHdpbmRvd1twXSAmJiB3aW5kb3dbcF0ubmFt
+ZSA9PSBwOwogICAgICB9CiAgICAgIGlmIChjb25maXJtKCJXaW5kb3ciKSAmJiBjb25maXJtKCJIVE1M
+RWxlbWVudCIpKSByZXR1cm4gaG9va3M7CiAgICB9CiAgICBob29rcy5nZXRUYWcgPSBnZXRUYWdGYWxs
+YmFjazsKICB9Owp9CkMuS1U9ZnVuY3Rpb24oaG9va3MpIHsKICBpZiAodHlwZW9mIGRhcnRFeHBlcmlt
+ZW50YWxGaXh1cEdldFRhZyAhPSAiZnVuY3Rpb24iKSByZXR1cm4gaG9va3M7CiAgaG9va3MuZ2V0VGFn
+ID0gZGFydEV4cGVyaW1lbnRhbEZpeHVwR2V0VGFnKGhvb2tzLmdldFRhZyk7Cn0KQy5mUT1mdW5jdGlv
+bihob29rcykgewogIHZhciBnZXRUYWcgPSBob29rcy5nZXRUYWc7CiAgdmFyIHByb3RvdHlwZUZvclRh
+ZyA9IGhvb2tzLnByb3RvdHlwZUZvclRhZzsKICBmdW5jdGlvbiBnZXRUYWdGaXhlZChvKSB7CiAgICB2
+YXIgdGFnID0gZ2V0VGFnKG8pOwogICAgaWYgKHRhZyA9PSAiRG9jdW1lbnQiKSB7CiAgICAgIGlmICgh
+IW8ueG1sVmVyc2lvbikgcmV0dXJuICIhRG9jdW1lbnQiOwogICAgICByZXR1cm4gIiFIVE1MRG9jdW1l
+bnQiOwogICAgfQogICAgcmV0dXJuIHRhZzsKICB9CiAgZnVuY3Rpb24gcHJvdG90eXBlRm9yVGFnRml4
+ZWQodGFnKSB7CiAgICBpZiAodGFnID09ICJEb2N1bWVudCIpIHJldHVybiBudWxsOwogICAgcmV0dXJu
+IHByb3RvdHlwZUZvclRhZyh0YWcpOwogIH0KICBob29rcy5nZXRUYWcgPSBnZXRUYWdGaXhlZDsKICBo
+b29rcy5wcm90b3R5cGVGb3JUYWcgPSBwcm90b3R5cGVGb3JUYWdGaXhlZDsKfQpDLmRrPWZ1bmN0aW9u
+KGhvb2tzKSB7CiAgdmFyIHVzZXJBZ2VudCA9IHR5cGVvZiBuYXZpZ2F0b3IgPT0gIm9iamVjdCIgPyBu
+YXZpZ2F0b3IudXNlckFnZW50IDogIiI7CiAgaWYgKHVzZXJBZ2VudC5pbmRleE9mKCJGaXJlZm94Iikg
+PT0gLTEpIHJldHVybiBob29rczsKICB2YXIgZ2V0VGFnID0gaG9va3MuZ2V0VGFnOwogIHZhciBxdWlj
+a01hcCA9IHsKICAgICJCZWZvcmVVbmxvYWRFdmVudCI6ICJFdmVudCIsCiAgICAiRGF0YVRyYW5zZmVy
+IjogIkNsaXBib2FyZCIsCiAgICAiR2VvR2VvbG9jYXRpb24iOiAiR2VvbG9jYXRpb24iLAogICAgIkxv
+Y2F0aW9uIjogIiFMb2NhdGlvbiIsCiAgICAiV29ya2VyTWVzc2FnZUV2ZW50IjogIk1lc3NhZ2VFdmVu
+dCIsCiAgICAiWE1MRG9jdW1lbnQiOiAiIURvY3VtZW50In07CiAgZnVuY3Rpb24gZ2V0VGFnRmlyZWZv
+eChvKSB7CiAgICB2YXIgdGFnID0gZ2V0VGFnKG8pOwogICAgcmV0dXJuIHF1aWNrTWFwW3RhZ10gfHwg
+dGFnOwogIH0KICBob29rcy5nZXRUYWcgPSBnZXRUYWdGaXJlZm94Owp9CkMueGk9ZnVuY3Rpb24oaG9v
+a3MpIHsKICB2YXIgdXNlckFnZW50ID0gdHlwZW9mIG5hdmlnYXRvciA9PSAib2JqZWN0IiA/IG5hdmln
+YXRvci51c2VyQWdlbnQgOiAiIjsKICBpZiAodXNlckFnZW50LmluZGV4T2YoIlRyaWRlbnQvIikgPT0g
+LTEpIHJldHVybiBob29rczsKICB2YXIgZ2V0VGFnID0gaG9va3MuZ2V0VGFnOwogIHZhciBxdWlja01h
+cCA9IHsKICAgICJCZWZvcmVVbmxvYWRFdmVudCI6ICJFdmVudCIsCiAgICAiRGF0YVRyYW5zZmVyIjog
+IkNsaXBib2FyZCIsCiAgICAiSFRNTERERWxlbWVudCI6ICJIVE1MRWxlbWVudCIsCiAgICAiSFRNTERU
+RWxlbWVudCI6ICJIVE1MRWxlbWVudCIsCiAgICAiSFRNTFBocmFzZUVsZW1lbnQiOiAiSFRNTEVsZW1l
+bnQiLAogICAgIlBvc2l0aW9uIjogIkdlb3Bvc2l0aW9uIgogIH07CiAgZnVuY3Rpb24gZ2V0VGFnSUUo
+bykgewogICAgdmFyIHRhZyA9IGdldFRhZyhvKTsKICAgIHZhciBuZXdUYWcgPSBxdWlja01hcFt0YWdd
+OwogICAgaWYgKG5ld1RhZykgcmV0dXJuIG5ld1RhZzsKICAgIGlmICh0YWcgPT0gIk9iamVjdCIpIHsK
+ICAgICAgaWYgKHdpbmRvdy5EYXRhVmlldyAmJiAobyBpbnN0YW5jZW9mIHdpbmRvdy5EYXRhVmlldykp
+IHJldHVybiAiRGF0YVZpZXciOwogICAgfQogICAgcmV0dXJuIHRhZzsKICB9CiAgZnVuY3Rpb24gcHJv
+dG90eXBlRm9yVGFnSUUodGFnKSB7CiAgICB2YXIgY29uc3RydWN0b3IgPSB3aW5kb3dbdGFnXTsKICAg
+IGlmIChjb25zdHJ1Y3RvciA9PSBudWxsKSByZXR1cm4gbnVsbDsKICAgIHJldHVybiBjb25zdHJ1Y3Rv
+ci5wcm90b3R5cGU7CiAgfQogIGhvb2tzLmdldFRhZyA9IGdldFRhZ0lFOwogIGhvb2tzLnByb3RvdHlw
+ZUZvclRhZyA9IHByb3RvdHlwZUZvclRhZ0lFOwp9CkMuaTc9ZnVuY3Rpb24oaG9va3MpIHsgcmV0dXJu
+IGhvb2tzOyB9CgpDLkN0PW5ldyBQLmJ5KCkKQy5FcT1uZXcgUC5rNSgpCkMueE09bmV3IFAudTUoKQpD
+LlFrPW5ldyBQLkUzKCkKQy5OVT1uZXcgUC5KaSgpCkMucGQ9bmV3IFAuWmQoKQpDLkEzPW5ldyBQLk14
+KG51bGwpCkMuR2I9SC5WTSh0KFsxMjcsMjA0Nyw2NTUzNSwxMTE0MTExXSksdS5WKQpDLmFrPUguVk0o
+dChbMCwwLDMyNzc2LDMzNzkyLDEsMTAyNDAsMCwwXSksdS5WKQpDLmNtPUguVk0odChbIio6OmNsYXNz
+IiwiKjo6ZGlyIiwiKjo6ZHJhZ2dhYmxlIiwiKjo6aGlkZGVuIiwiKjo6aWQiLCIqOjppbmVydCIsIio6
+Oml0ZW1wcm9wIiwiKjo6aXRlbXJlZiIsIio6Oml0ZW1zY29wZSIsIio6OmxhbmciLCIqOjpzcGVsbGNo
+ZWNrIiwiKjo6dGl0bGUiLCIqOjp0cmFuc2xhdGUiLCJBOjphY2Nlc3NrZXkiLCJBOjpjb29yZHMiLCJB
+OjpocmVmbGFuZyIsIkE6Om5hbWUiLCJBOjpzaGFwZSIsIkE6OnRhYmluZGV4IiwiQTo6dGFyZ2V0Iiwi
+QTo6dHlwZSIsIkFSRUE6OmFjY2Vzc2tleSIsIkFSRUE6OmFsdCIsIkFSRUE6OmNvb3JkcyIsIkFSRUE6
+Om5vaHJlZiIsIkFSRUE6OnNoYXBlIiwiQVJFQTo6dGFiaW5kZXgiLCJBUkVBOjp0YXJnZXQiLCJBVURJ
+Tzo6Y29udHJvbHMiLCJBVURJTzo6bG9vcCIsIkFVRElPOjptZWRpYWdyb3VwIiwiQVVESU86Om11dGVk
+IiwiQVVESU86OnByZWxvYWQiLCJCRE86OmRpciIsIkJPRFk6OmFsaW5rIiwiQk9EWTo6Ymdjb2xvciIs
+IkJPRFk6OmxpbmsiLCJCT0RZOjp0ZXh0IiwiQk9EWTo6dmxpbmsiLCJCUjo6Y2xlYXIiLCJCVVRUT046
+OmFjY2Vzc2tleSIsIkJVVFRPTjo6ZGlzYWJsZWQiLCJCVVRUT046Om5hbWUiLCJCVVRUT046OnRhYmlu
+ZGV4IiwiQlVUVE9OOjp0eXBlIiwiQlVUVE9OOjp2YWx1ZSIsIkNBTlZBUzo6aGVpZ2h0IiwiQ0FOVkFT
+Ojp3aWR0aCIsIkNBUFRJT046OmFsaWduIiwiQ09MOjphbGlnbiIsIkNPTDo6Y2hhciIsIkNPTDo6Y2hh
+cm9mZiIsIkNPTDo6c3BhbiIsIkNPTDo6dmFsaWduIiwiQ09MOjp3aWR0aCIsIkNPTEdST1VQOjphbGln
+biIsIkNPTEdST1VQOjpjaGFyIiwiQ09MR1JPVVA6OmNoYXJvZmYiLCJDT0xHUk9VUDo6c3BhbiIsIkNP
+TEdST1VQOjp2YWxpZ24iLCJDT0xHUk9VUDo6d2lkdGgiLCJDT01NQU5EOjpjaGVja2VkIiwiQ09NTUFO
+RDo6Y29tbWFuZCIsIkNPTU1BTkQ6OmRpc2FibGVkIiwiQ09NTUFORDo6bGFiZWwiLCJDT01NQU5EOjpy
+YWRpb2dyb3VwIiwiQ09NTUFORDo6dHlwZSIsIkRBVEE6OnZhbHVlIiwiREVMOjpkYXRldGltZSIsIkRF
+VEFJTFM6Om9wZW4iLCJESVI6OmNvbXBhY3QiLCJESVY6OmFsaWduIiwiREw6OmNvbXBhY3QiLCJGSUVM
+RFNFVDo6ZGlzYWJsZWQiLCJGT05UOjpjb2xvciIsIkZPTlQ6OmZhY2UiLCJGT05UOjpzaXplIiwiRk9S
+TTo6YWNjZXB0IiwiRk9STTo6YXV0b2NvbXBsZXRlIiwiRk9STTo6ZW5jdHlwZSIsIkZPUk06Om1ldGhv
+ZCIsIkZPUk06Om5hbWUiLCJGT1JNOjpub3ZhbGlkYXRlIiwiRk9STTo6dGFyZ2V0IiwiRlJBTUU6Om5h
+bWUiLCJIMTo6YWxpZ24iLCJIMjo6YWxpZ24iLCJIMzo6YWxpZ24iLCJINDo6YWxpZ24iLCJINTo6YWxp
+Z24iLCJINjo6YWxpZ24iLCJIUjo6YWxpZ24iLCJIUjo6bm9zaGFkZSIsIkhSOjpzaXplIiwiSFI6Ondp
+ZHRoIiwiSFRNTDo6dmVyc2lvbiIsIklGUkFNRTo6YWxpZ24iLCJJRlJBTUU6OmZyYW1lYm9yZGVyIiwi
+SUZSQU1FOjpoZWlnaHQiLCJJRlJBTUU6Om1hcmdpbmhlaWdodCIsIklGUkFNRTo6bWFyZ2lud2lkdGgi
+LCJJRlJBTUU6OndpZHRoIiwiSU1HOjphbGlnbiIsIklNRzo6YWx0IiwiSU1HOjpib3JkZXIiLCJJTUc6
+OmhlaWdodCIsIklNRzo6aHNwYWNlIiwiSU1HOjppc21hcCIsIklNRzo6bmFtZSIsIklNRzo6dXNlbWFw
+IiwiSU1HOjp2c3BhY2UiLCJJTUc6OndpZHRoIiwiSU5QVVQ6OmFjY2VwdCIsIklOUFVUOjphY2Nlc3Nr
+ZXkiLCJJTlBVVDo6YWxpZ24iLCJJTlBVVDo6YWx0IiwiSU5QVVQ6OmF1dG9jb21wbGV0ZSIsIklOUFVU
+OjphdXRvZm9jdXMiLCJJTlBVVDo6Y2hlY2tlZCIsIklOUFVUOjpkaXNhYmxlZCIsIklOUFVUOjppbnB1
+dG1vZGUiLCJJTlBVVDo6aXNtYXAiLCJJTlBVVDo6bGlzdCIsIklOUFVUOjptYXgiLCJJTlBVVDo6bWF4
+bGVuZ3RoIiwiSU5QVVQ6Om1pbiIsIklOUFVUOjptdWx0aXBsZSIsIklOUFVUOjpuYW1lIiwiSU5QVVQ6
+OnBsYWNlaG9sZGVyIiwiSU5QVVQ6OnJlYWRvbmx5IiwiSU5QVVQ6OnJlcXVpcmVkIiwiSU5QVVQ6OnNp
+emUiLCJJTlBVVDo6c3RlcCIsIklOUFVUOjp0YWJpbmRleCIsIklOUFVUOjp0eXBlIiwiSU5QVVQ6OnVz
+ZW1hcCIsIklOUFVUOjp2YWx1ZSIsIklOUzo6ZGF0ZXRpbWUiLCJLRVlHRU46OmRpc2FibGVkIiwiS0VZ
+R0VOOjprZXl0eXBlIiwiS0VZR0VOOjpuYW1lIiwiTEFCRUw6OmFjY2Vzc2tleSIsIkxBQkVMOjpmb3Ii
+LCJMRUdFTkQ6OmFjY2Vzc2tleSIsIkxFR0VORDo6YWxpZ24iLCJMSTo6dHlwZSIsIkxJOjp2YWx1ZSIs
+IkxJTks6OnNpemVzIiwiTUFQOjpuYW1lIiwiTUVOVTo6Y29tcGFjdCIsIk1FTlU6OmxhYmVsIiwiTUVO
+VTo6dHlwZSIsIk1FVEVSOjpoaWdoIiwiTUVURVI6OmxvdyIsIk1FVEVSOjptYXgiLCJNRVRFUjo6bWlu
+IiwiTUVURVI6OnZhbHVlIiwiT0JKRUNUOjp0eXBlbXVzdG1hdGNoIiwiT0w6OmNvbXBhY3QiLCJPTDo6
+cmV2ZXJzZWQiLCJPTDo6c3RhcnQiLCJPTDo6dHlwZSIsIk9QVEdST1VQOjpkaXNhYmxlZCIsIk9QVEdS
+T1VQOjpsYWJlbCIsIk9QVElPTjo6ZGlzYWJsZWQiLCJPUFRJT046OmxhYmVsIiwiT1BUSU9OOjpzZWxl
+Y3RlZCIsIk9QVElPTjo6dmFsdWUiLCJPVVRQVVQ6OmZvciIsIk9VVFBVVDo6bmFtZSIsIlA6OmFsaWdu
+IiwiUFJFOjp3aWR0aCIsIlBST0dSRVNTOjptYXgiLCJQUk9HUkVTUzo6bWluIiwiUFJPR1JFU1M6OnZh
+bHVlIiwiU0VMRUNUOjphdXRvY29tcGxldGUiLCJTRUxFQ1Q6OmRpc2FibGVkIiwiU0VMRUNUOjptdWx0
+aXBsZSIsIlNFTEVDVDo6bmFtZSIsIlNFTEVDVDo6cmVxdWlyZWQiLCJTRUxFQ1Q6OnNpemUiLCJTRUxF
+Q1Q6OnRhYmluZGV4IiwiU09VUkNFOjp0eXBlIiwiVEFCTEU6OmFsaWduIiwiVEFCTEU6OmJnY29sb3Ii
+LCJUQUJMRTo6Ym9yZGVyIiwiVEFCTEU6OmNlbGxwYWRkaW5nIiwiVEFCTEU6OmNlbGxzcGFjaW5nIiwi
+VEFCTEU6OmZyYW1lIiwiVEFCTEU6OnJ1bGVzIiwiVEFCTEU6OnN1bW1hcnkiLCJUQUJMRTo6d2lkdGgi
+LCJUQk9EWTo6YWxpZ24iLCJUQk9EWTo6Y2hhciIsIlRCT0RZOjpjaGFyb2ZmIiwiVEJPRFk6OnZhbGln
+biIsIlREOjphYmJyIiwiVEQ6OmFsaWduIiwiVEQ6OmF4aXMiLCJURDo6Ymdjb2xvciIsIlREOjpjaGFy
+IiwiVEQ6OmNoYXJvZmYiLCJURDo6Y29sc3BhbiIsIlREOjpoZWFkZXJzIiwiVEQ6OmhlaWdodCIsIlRE
+Ojpub3dyYXAiLCJURDo6cm93c3BhbiIsIlREOjpzY29wZSIsIlREOjp2YWxpZ24iLCJURDo6d2lkdGgi
+LCJURVhUQVJFQTo6YWNjZXNza2V5IiwiVEVYVEFSRUE6OmF1dG9jb21wbGV0ZSIsIlRFWFRBUkVBOjpj
+b2xzIiwiVEVYVEFSRUE6OmRpc2FibGVkIiwiVEVYVEFSRUE6OmlucHV0bW9kZSIsIlRFWFRBUkVBOjpu
+YW1lIiwiVEVYVEFSRUE6OnBsYWNlaG9sZGVyIiwiVEVYVEFSRUE6OnJlYWRvbmx5IiwiVEVYVEFSRUE6
+OnJlcXVpcmVkIiwiVEVYVEFSRUE6OnJvd3MiLCJURVhUQVJFQTo6dGFiaW5kZXgiLCJURVhUQVJFQTo6
+d3JhcCIsIlRGT09UOjphbGlnbiIsIlRGT09UOjpjaGFyIiwiVEZPT1Q6OmNoYXJvZmYiLCJURk9PVDo6
+dmFsaWduIiwiVEg6OmFiYnIiLCJUSDo6YWxpZ24iLCJUSDo6YXhpcyIsIlRIOjpiZ2NvbG9yIiwiVEg6
+OmNoYXIiLCJUSDo6Y2hhcm9mZiIsIlRIOjpjb2xzcGFuIiwiVEg6OmhlYWRlcnMiLCJUSDo6aGVpZ2h0
+IiwiVEg6Om5vd3JhcCIsIlRIOjpyb3dzcGFuIiwiVEg6OnNjb3BlIiwiVEg6OnZhbGlnbiIsIlRIOjp3
+aWR0aCIsIlRIRUFEOjphbGlnbiIsIlRIRUFEOjpjaGFyIiwiVEhFQUQ6OmNoYXJvZmYiLCJUSEVBRDo6
+dmFsaWduIiwiVFI6OmFsaWduIiwiVFI6OmJnY29sb3IiLCJUUjo6Y2hhciIsIlRSOjpjaGFyb2ZmIiwi
+VFI6OnZhbGlnbiIsIlRSQUNLOjpkZWZhdWx0IiwiVFJBQ0s6OmtpbmQiLCJUUkFDSzo6bGFiZWwiLCJU
+UkFDSzo6c3JjbGFuZyIsIlVMOjpjb21wYWN0IiwiVUw6OnR5cGUiLCJWSURFTzo6Y29udHJvbHMiLCJW
+SURFTzo6aGVpZ2h0IiwiVklERU86Omxvb3AiLCJWSURFTzo6bWVkaWFncm91cCIsIlZJREVPOjptdXRl
+ZCIsIlZJREVPOjpwcmVsb2FkIiwiVklERU86OndpZHRoIl0pLHUuaSkKQy5WQz1ILlZNKHQoWzAsMCw2
+NTQ5MCw0NTA1NSw2NTUzNSwzNDgxNSw2NTUzNCwxODQzMV0pLHUuVikKQy5tSz1ILlZNKHQoWzAsMCwy
+NjYyNCwxMDIzLDY1NTM0LDIwNDcsNjU1MzQsMjA0N10pLHUuVikKQy5TcT1ILlZNKHQoWyJIRUFEIiwi
+QVJFQSIsIkJBU0UiLCJCQVNFRk9OVCIsIkJSIiwiQ09MIiwiQ09MR1JPVVAiLCJFTUJFRCIsIkZSQU1F
+IiwiRlJBTUVTRVQiLCJIUiIsIklNQUdFIiwiSU1HIiwiSU5QVVQiLCJJU0lOREVYIiwiTElOSyIsIk1F
+VEEiLCJQQVJBTSIsIlNPVVJDRSIsIlNUWUxFIiwiVElUTEUiLCJXQlIiXSksdS5pKQpDLmRuPUguVk0o
+dChbXSksdS5iKQpDLnhEPUguVk0odChbXSksdS5pKQpDLnRvPUguVk0odChbMCwwLDMyNzIyLDEyMjg3
+LDY1NTM0LDM0ODE1LDY1NTM0LDE4NDMxXSksdS5WKQpDLkYzPUguVk0odChbMCwwLDI0NTc2LDEwMjMs
+NjU1MzQsMzQ4MTUsNjU1MzQsMTg0MzFdKSx1LlYpCkMuZWE9SC5WTSh0KFswLDAsMzI3NTQsMTEyNjMs
+NjU1MzQsMzQ4MTUsNjU1MzQsMTg0MzFdKSx1LlYpCkMuWko9SC5WTSh0KFswLDAsMzI3MjIsMTIyODcs
+NjU1MzUsMzQ4MTUsNjU1MzQsMTg0MzFdKSx1LlYpCkMuV2Q9SC5WTSh0KFswLDAsNjU0OTAsMTIyODcs
+NjU1MzUsMzQ4MTUsNjU1MzQsMTg0MzFdKSx1LlYpCkMuUXg9SC5WTSh0KFsiYmluZCIsImlmIiwicmVm
+IiwicmVwZWF0Iiwic3ludGF4Il0pLHUuaSkKQy5CST1ILlZNKHQoWyJBOjpocmVmIiwiQVJFQTo6aHJl
+ZiIsIkJMT0NLUVVPVEU6OmNpdGUiLCJCT0RZOjpiYWNrZ3JvdW5kIiwiQ09NTUFORDo6aWNvbiIsIkRF
+TDo6Y2l0ZSIsIkZPUk06OmFjdGlvbiIsIklNRzo6c3JjIiwiSU5QVVQ6OnNyYyIsIklOUzo6Y2l0ZSIs
+IlE6OmNpdGUiLCJWSURFTzo6cG9zdGVyIl0pLHUuaSkKQy5DTT1uZXcgSC5MUCgwLHt9LEMueEQsSC5O
+MCgiTFA8cVUqLHpNPGo4Kj4qPiIpKQpDLldPPW5ldyBILkxQKDAse30sQy54RCxILk4wKCJMUDxxVSos
+cVUqPiIpKQpDLmhVPUguVk0odChbXSksSC5OMCgiamQ8R0QqPiIpKQpDLkR4PW5ldyBILkxQKDAse30s
+Qy5oVSxILk4wKCJMUDxHRCosQD4iKSkKQy5ZMj1uZXcgTC5POSgiTmF2aWdhdGlvblRyZWVOb2RlVHlw
+ZS5kaXJlY3RvcnkiKQpDLnJmPW5ldyBMLk85KCJOYXZpZ2F0aW9uVHJlZU5vZGVUeXBlLmZpbGUiKQpD
+LlRlPW5ldyBILnd2KCJjYWxsIikKQy53UT1uZXcgUC5GeShudWxsLDIpfSkoKTsoZnVuY3Rpb24gc3Rh
+dGljRmllbGRzKCl7JC56bT1udWxsCiQueWo9MAokLm1KPW51bGwKJC5QND1udWxsCiQuTkY9bnVsbAok
+LlRYPW51bGwKJC54Nz1udWxsCiQubnc9bnVsbAokLnZ2PW51bGwKJC5Cdj1udWxsCiQuUzY9bnVsbAok
+Lms4PW51bGwKJC5tZz1udWxsCiQuVUQ9ITEKJC5YMz1DLk5VCiQueGc9SC5WTShbXSxILk4wKCJqZDxN
+aD4iKSkKJC54bz1udWxsCiQuQk89bnVsbAokLmx0PW51bGwKJC5FVT1udWxsCiQub3I9UC5GbCh1Lk4s
+dS5ZKQokLkk2PW51bGwKJC5GZj1udWxsfSkoKTsoZnVuY3Rpb24gbGF6eUluaXRpYWxpemVycygpe3Zh
+ciB0PWh1bmtIZWxwZXJzLmxhenkKdCgkLCJmYSIsInciLGZ1bmN0aW9uKCl7cmV0dXJuIEguWWcoIl8k
+ZGFydF9kYXJ0Q2xvc3VyZSIpfSkKdCgkLCJVMiIsIlNuIixmdW5jdGlvbigpe3JldHVybiBILmNNKEgu
+Uzcoewp0b1N0cmluZzpmdW5jdGlvbigpe3JldHVybiIkcmVjZWl2ZXIkIn19KSl9KQp0KCQsInhxIiwi
+bHEiLGZ1bmN0aW9uKCl7cmV0dXJuIEguY00oSC5TNyh7JG1ldGhvZCQ6bnVsbCwKdG9TdHJpbmc6ZnVu
+Y3Rpb24oKXtyZXR1cm4iJHJlY2VpdmVyJCJ9fSkpfSkKdCgkLCJSMSIsIk45IixmdW5jdGlvbigpe3Jl
+dHVybiBILmNNKEguUzcobnVsbCkpfSkKdCgkLCJmTiIsImlJIixmdW5jdGlvbigpe3JldHVybiBILmNN
+KGZ1bmN0aW9uKCl7dmFyICRhcmd1bWVudHNFeHByJD0nJGFyZ3VtZW50cyQnCnRyeXtudWxsLiRtZXRo
+b2QkKCRhcmd1bWVudHNFeHByJCl9Y2F0Y2gocyl7cmV0dXJuIHMubWVzc2FnZX19KCkpfSkKdCgkLCJx
+aSIsIlVOIixmdW5jdGlvbigpe3JldHVybiBILmNNKEguUzcodm9pZCAwKSl9KQp0KCQsInJaIiwiWmgi
+LGZ1bmN0aW9uKCl7cmV0dXJuIEguY00oZnVuY3Rpb24oKXt2YXIgJGFyZ3VtZW50c0V4cHIkPSckYXJn
+dW1lbnRzJCcKdHJ5eyh2b2lkIDApLiRtZXRob2QkKCRhcmd1bWVudHNFeHByJCl9Y2F0Y2gocyl7cmV0
+dXJuIHMubWVzc2FnZX19KCkpfSkKdCgkLCJrcSIsInJOIixmdW5jdGlvbigpe3JldHVybiBILmNNKEgu
+TWoobnVsbCkpfSkKdCgkLCJ0dCIsImMzIixmdW5jdGlvbigpe3JldHVybiBILmNNKGZ1bmN0aW9uKCl7
+dHJ5e251bGwuJG1ldGhvZCR9Y2F0Y2gocyl7cmV0dXJuIHMubWVzc2FnZX19KCkpfSkKdCgkLCJkdCIs
+IkhLIixmdW5jdGlvbigpe3JldHVybiBILmNNKEguTWoodm9pZCAwKSl9KQp0KCQsIkE3IiwicjEiLGZ1
+bmN0aW9uKCl7cmV0dXJuIEguY00oZnVuY3Rpb24oKXt0cnl7KHZvaWQgMCkuJG1ldGhvZCR9Y2F0Y2go
+cyl7cmV0dXJuIHMubWVzc2FnZX19KCkpfSkKdCgkLCJXYyIsInV0IixmdW5jdGlvbigpe3JldHVybiBQ
+Lk9qKCl9KQp0KCQsImtoIiwicmYiLGZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBQLnBnKCkuJDAoKX0pCnQo
+JCwiYnQiLCJWNyIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEludDhBcnJheShILlhGKEguVk0oWy0yLC0y
+LC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0y
+LC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0yLC0xLC0yLC0yLC0yLC0y
+LC0yLDYyLC0yLDYyLC0yLDYzLDUyLDUzLDU0LDU1LDU2LDU3LDU4LDU5LDYwLDYxLC0yLC0yLC0yLC0x
+LC0yLC0yLC0yLDAsMSwyLDMsNCw1LDYsNyw4LDksMTAsMTEsMTIsMTMsMTQsMTUsMTYsMTcsMTgsMTks
+MjAsMjEsMjIsMjMsMjQsMjUsLTIsLTIsLTIsLTIsNjMsLTIsMjYsMjcsMjgsMjksMzAsMzEsMzIsMzMs
+MzQsMzUsMzYsMzcsMzgsMzksNDAsNDEsNDIsNDMsNDQsNDUsNDYsNDcsNDgsNDksNTAsNTEsLTIsLTIs
+LTIsLTIsLTJdLHUudCkpKX0pCnQoJCwiTTUiLCJ3USIsZnVuY3Rpb24oKXtyZXR1cm4gdHlwZW9mIHBy
+b2Nlc3MhPSJ1bmRlZmluZWQiJiZPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwocHJvY2Vzcyk9
+PSJbb2JqZWN0IHByb2Nlc3NdIiYmcHJvY2Vzcy5wbGF0Zm9ybT09IndpbjMyIn0pCnQoJCwibWYiLCJ6
+NCIsZnVuY3Rpb24oKXtyZXR1cm4gUC5udSgiXltcXC1cXC4wLTlBLVpfYS16fl0qJCIpfSkKdCgkLCJK
+RyIsInZaIixmdW5jdGlvbigpe3JldHVybiBQLktOKCl9KQp0KCQsIlNDIiwiQU4iLGZ1bmN0aW9uKCl7
+cmV0dXJuIFAudE0oWyJBIiwiQUJCUiIsIkFDUk9OWU0iLCJBRERSRVNTIiwiQVJFQSIsIkFSVElDTEUi
+LCJBU0lERSIsIkFVRElPIiwiQiIsIkJESSIsIkJETyIsIkJJRyIsIkJMT0NLUVVPVEUiLCJCUiIsIkJV
+VFRPTiIsIkNBTlZBUyIsIkNBUFRJT04iLCJDRU5URVIiLCJDSVRFIiwiQ09ERSIsIkNPTCIsIkNPTEdS
+T1VQIiwiQ09NTUFORCIsIkRBVEEiLCJEQVRBTElTVCIsIkREIiwiREVMIiwiREVUQUlMUyIsIkRGTiIs
+IkRJUiIsIkRJViIsIkRMIiwiRFQiLCJFTSIsIkZJRUxEU0VUIiwiRklHQ0FQVElPTiIsIkZJR1VSRSIs
+IkZPTlQiLCJGT09URVIiLCJGT1JNIiwiSDEiLCJIMiIsIkgzIiwiSDQiLCJINSIsIkg2IiwiSEVBREVS
+IiwiSEdST1VQIiwiSFIiLCJJIiwiSUZSQU1FIiwiSU1HIiwiSU5QVVQiLCJJTlMiLCJLQkQiLCJMQUJF
+TCIsIkxFR0VORCIsIkxJIiwiTUFQIiwiTUFSSyIsIk1FTlUiLCJNRVRFUiIsIk5BViIsIk5PQlIiLCJP
+TCIsIk9QVEdST1VQIiwiT1BUSU9OIiwiT1VUUFVUIiwiUCIsIlBSRSIsIlBST0dSRVNTIiwiUSIsIlMi
+LCJTQU1QIiwiU0VDVElPTiIsIlNFTEVDVCIsIlNNQUxMIiwiU09VUkNFIiwiU1BBTiIsIlNUUklLRSIs
+IlNUUk9ORyIsIlNVQiIsIlNVTU1BUlkiLCJTVVAiLCJUQUJMRSIsIlRCT0RZIiwiVEQiLCJURVhUQVJF
+QSIsIlRGT09UIiwiVEgiLCJUSEVBRCIsIlRJTUUiLCJUUiIsIlRSQUNLIiwiVFQiLCJVIiwiVUwiLCJW
+QVIiLCJWSURFTyIsIldCUiJdLHUuTil9KQp0KCQsIlg0IiwiaEciLGZ1bmN0aW9uKCl7cmV0dXJuIFAu
+bnUoIl5cXFMrJCIpfSkKdCgkLCJ3TyIsIm93IixmdW5jdGlvbigpe3JldHVybiBQLk5EKHNlbGYpfSkK
+dCgkLCJrdCIsIlI4IixmdW5jdGlvbigpe3JldHVybiBILllnKCJfJGRhcnRfZGFydE9iamVjdCIpfSkK
+dCgkLCJmSyIsImtJIixmdW5jdGlvbigpe3JldHVybiBmdW5jdGlvbiBEYXJ0T2JqZWN0KGEpe3RoaXMu
+bz1hfX0pCnQoJCwicXQiLCJ6QiIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3IFQubVEoKX0pCnQoJCwiT2wi
+LCJVRSIsZnVuY3Rpb24oKXtyZXR1cm4gUC5oSyhDLm9sLmdtVyhXLngzKCkpLmhyZWYpLmdoWSgpLnEo
+MCwiYXV0aFRva2VuIil9KQp0KCQsImhUIiwieVAiLGZ1bmN0aW9uKCl7cmV0dXJuIFcuWnIoKS5xdWVy
+eVNlbGVjdG9yKCIuZWRpdC1saXN0IC5wYW5lbC1jb250ZW50Iil9KQp0KCQsIlc2IiwiaEwiLGZ1bmN0
+aW9uKCl7cmV0dXJuIFcuWnIoKS5xdWVyeVNlbGVjdG9yKCIuZWRpdC1wYW5lbCAucGFuZWwtY29udGVu
+dCIpfSkKdCgkLCJUUiIsIkRXIixmdW5jdGlvbigpe3JldHVybiBXLlpyKCkucXVlcnlTZWxlY3Rvcigi
+Zm9vdGVyIil9KQp0KCQsIkVZIiwiZmkiLGZ1bmN0aW9uKCl7cmV0dXJuIFcuWnIoKS5xdWVyeVNlbGVj
+dG9yKCJoZWFkZXIiKX0pCnQoJCwiYXYiLCJEOSIsZnVuY3Rpb24oKXtyZXR1cm4gVy5acigpLnF1ZXJ5
+U2VsZWN0b3IoIiN1bml0LW5hbWUiKX0pCnQoJCwiZmUiLCJLRyIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3
+IEwuWEEoKX0pCnQoJCwiZW8iLCJuVSIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3IE0ubEkoJC5IaygpKX0p
+CnQoJCwieXIiLCJiRCIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEUuT0YoUC5udSgiLyIpLFAubnUoIlte
+L10kIiksUC5udSgiXi8iKSl9KQp0KCQsIk1rIiwiS2siLGZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBMLklW
+KFAubnUoIlsvXFxcXF0iKSxQLm51KCJbXi9cXFxcXSQiKSxQLm51KCJeKFxcXFxcXFxcW15cXFxcXStc
+XFxcW15cXFxcL10rfFthLXpBLVpdOlsvXFxcXF0pIiksUC5udSgiXlsvXFxcXF0oPyFbL1xcXFxdKSIp
+KX0pCnQoJCwiYWsiLCJFYiIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEYucnUoUC5udSgiLyIpLFAubnUo
+IiheW2EtekEtWl1bLSsuYS16QS1aXFxkXSo6Ly98W14vXSkkIiksUC5udSgiW2EtekEtWl1bLSsuYS16
+QS1aXFxkXSo6Ly9bXi9dKiIpLFAubnUoIl4vIikpfSkKdCgkLCJscyIsIkhrIixmdW5jdGlvbigpe3Jl
+dHVybiBPLlJoKCl9KX0pKCk7KGZ1bmN0aW9uIG5hdGl2ZVN1cHBvcnQoKXshZnVuY3Rpb24oKXt2YXIg
+dD1mdW5jdGlvbihhKXt2YXIgbj17fQpuW2FdPTEKcmV0dXJuIE9iamVjdC5rZXlzKGh1bmtIZWxwZXJz
+LmNvbnZlcnRUb0Zhc3RPYmplY3QobikpWzBdfQp2LmdldElzb2xhdGVUYWc9ZnVuY3Rpb24oYSl7cmV0
+dXJuIHQoIl9fX2RhcnRfIithK3YuaXNvbGF0ZVRhZyl9CnZhciBzPSJfX19kYXJ0X2lzb2xhdGVfdGFn
+c18iCnZhciByPU9iamVjdFtzXXx8KE9iamVjdFtzXT1PYmplY3QuY3JlYXRlKG51bGwpKQp2YXIgcT0i
+X1p4WXhYIgpmb3IodmFyIHA9MDs7cCsrKXt2YXIgbz10KHErIl8iK3ArIl8iKQppZighKG8gaW4gcikp
+e3Jbb109MQp2Lmlzb2xhdGVUYWc9bwpicmVha319di5kaXNwYXRjaFByb3BlcnR5TmFtZT12LmdldElz
+b2xhdGVUYWcoImRpc3BhdGNoX3JlY29yZCIpfSgpCmh1bmtIZWxwZXJzLnNldE9yVXBkYXRlSW50ZXJj
+ZXB0b3JzQnlUYWcoe0RPTUVycm9yOkoudkIsTWVkaWFFcnJvcjpKLnZCLE5hdmlnYXRvcjpKLnZCLE5h
+dmlnYXRvckNvbmN1cnJlbnRIYXJkd2FyZTpKLnZCLE5hdmlnYXRvclVzZXJNZWRpYUVycm9yOkoudkIs
+T3ZlcmNvbnN0cmFpbmVkRXJyb3I6Si52QixQb3NpdGlvbkVycm9yOkoudkIsUmFuZ2U6Si52QixTUUxF
+cnJvcjpKLnZCLERhdGFWaWV3OkguRVQsQXJyYXlCdWZmZXJWaWV3OkguRVQsRmxvYXQzMkFycmF5Okgu
+RGcsRmxvYXQ2NEFycmF5OkguRGcsSW50MTZBcnJheTpILnhqLEludDMyQXJyYXk6SC5kRSxJbnQ4QXJy
+YXk6SC5aQSxVaW50MTZBcnJheTpILmRULFVpbnQzMkFycmF5OkguUHEsVWludDhDbGFtcGVkQXJyYXk6
+SC5lRSxDYW52YXNQaXhlbEFycmF5OkguZUUsVWludDhBcnJheTpILlY2LEhUTUxBdWRpb0VsZW1lbnQ6
+Vy5xRSxIVE1MQlJFbGVtZW50OlcucUUsSFRNTEJ1dHRvbkVsZW1lbnQ6Vy5xRSxIVE1MQ2FudmFzRWxl
+bWVudDpXLnFFLEhUTUxDb250ZW50RWxlbWVudDpXLnFFLEhUTUxETGlzdEVsZW1lbnQ6Vy5xRSxIVE1M
+RGF0YUVsZW1lbnQ6Vy5xRSxIVE1MRGF0YUxpc3RFbGVtZW50OlcucUUsSFRNTERldGFpbHNFbGVtZW50
+OlcucUUsSFRNTERpYWxvZ0VsZW1lbnQ6Vy5xRSxIVE1MRGl2RWxlbWVudDpXLnFFLEhUTUxFbWJlZEVs
+ZW1lbnQ6Vy5xRSxIVE1MRmllbGRTZXRFbGVtZW50OlcucUUsSFRNTEhSRWxlbWVudDpXLnFFLEhUTUxI
+ZWFkRWxlbWVudDpXLnFFLEhUTUxIZWFkaW5nRWxlbWVudDpXLnFFLEhUTUxIdG1sRWxlbWVudDpXLnFF
+LEhUTUxJRnJhbWVFbGVtZW50OlcucUUsSFRNTEltYWdlRWxlbWVudDpXLnFFLEhUTUxJbnB1dEVsZW1l
+bnQ6Vy5xRSxIVE1MTElFbGVtZW50OlcucUUsSFRNTExhYmVsRWxlbWVudDpXLnFFLEhUTUxMZWdlbmRF
+bGVtZW50OlcucUUsSFRNTExpbmtFbGVtZW50OlcucUUsSFRNTE1hcEVsZW1lbnQ6Vy5xRSxIVE1MTWVk
+aWFFbGVtZW50OlcucUUsSFRNTE1lbnVFbGVtZW50OlcucUUsSFRNTE1ldGFFbGVtZW50OlcucUUsSFRN
+TE1ldGVyRWxlbWVudDpXLnFFLEhUTUxNb2RFbGVtZW50OlcucUUsSFRNTE9MaXN0RWxlbWVudDpXLnFF
+LEhUTUxPYmplY3RFbGVtZW50OlcucUUsSFRNTE9wdEdyb3VwRWxlbWVudDpXLnFFLEhUTUxPcHRpb25F
+bGVtZW50OlcucUUsSFRNTE91dHB1dEVsZW1lbnQ6Vy5xRSxIVE1MUGFyYW1FbGVtZW50OlcucUUsSFRN
+TFBpY3R1cmVFbGVtZW50OlcucUUsSFRNTFByZUVsZW1lbnQ6Vy5xRSxIVE1MUHJvZ3Jlc3NFbGVtZW50
+OlcucUUsSFRNTFF1b3RlRWxlbWVudDpXLnFFLEhUTUxTY3JpcHRFbGVtZW50OlcucUUsSFRNTFNoYWRv
+d0VsZW1lbnQ6Vy5xRSxIVE1MU2xvdEVsZW1lbnQ6Vy5xRSxIVE1MU291cmNlRWxlbWVudDpXLnFFLEhU
+TUxTcGFuRWxlbWVudDpXLnFFLEhUTUxTdHlsZUVsZW1lbnQ6Vy5xRSxIVE1MVGFibGVDYXB0aW9uRWxl
+bWVudDpXLnFFLEhUTUxUYWJsZUNlbGxFbGVtZW50OlcucUUsSFRNTFRhYmxlRGF0YUNlbGxFbGVtZW50
+OlcucUUsSFRNTFRhYmxlSGVhZGVyQ2VsbEVsZW1lbnQ6Vy5xRSxIVE1MVGFibGVDb2xFbGVtZW50Olcu
+cUUsSFRNTFRleHRBcmVhRWxlbWVudDpXLnFFLEhUTUxUaW1lRWxlbWVudDpXLnFFLEhUTUxUaXRsZUVs
+ZW1lbnQ6Vy5xRSxIVE1MVHJhY2tFbGVtZW50OlcucUUsSFRNTFVMaXN0RWxlbWVudDpXLnFFLEhUTUxV
+bmtub3duRWxlbWVudDpXLnFFLEhUTUxWaWRlb0VsZW1lbnQ6Vy5xRSxIVE1MRGlyZWN0b3J5RWxlbWVu
+dDpXLnFFLEhUTUxGb250RWxlbWVudDpXLnFFLEhUTUxGcmFtZUVsZW1lbnQ6Vy5xRSxIVE1MRnJhbWVT
+ZXRFbGVtZW50OlcucUUsSFRNTE1hcnF1ZWVFbGVtZW50OlcucUUsSFRNTEVsZW1lbnQ6Vy5xRSxIVE1M
+QW5jaG9yRWxlbWVudDpXLkdoLEhUTUxBcmVhRWxlbWVudDpXLmZZLEhUTUxCYXNlRWxlbWVudDpXLm5C
+LEJsb2I6Vy5BeixIVE1MQm9keUVsZW1lbnQ6Vy5RUCxDREFUQVNlY3Rpb246Vy5ueCxDaGFyYWN0ZXJE
+YXRhOlcubngsQ29tbWVudDpXLm54LFByb2Nlc3NpbmdJbnN0cnVjdGlvbjpXLm54LFRleHQ6Vy5ueCxD
+U1NTdHlsZURlY2xhcmF0aW9uOlcub0osTVNTdHlsZUNTU1Byb3BlcnRpZXM6Vy5vSixDU1MyUHJvcGVy
+dGllczpXLm9KLFhNTERvY3VtZW50OlcuUUYsRG9jdW1lbnQ6Vy5RRixET01FeGNlcHRpb246Vy5OaCxE
+T01JbXBsZW1lbnRhdGlvbjpXLmFlLERPTVJlY3RSZWFkT25seTpXLklCLERPTVRva2VuTGlzdDpXLm43
+LEVsZW1lbnQ6Vy5jdixBYm9ydFBheW1lbnRFdmVudDpXLmVhLEFuaW1hdGlvbkV2ZW50OlcuZWEsQW5p
+bWF0aW9uUGxheWJhY2tFdmVudDpXLmVhLEFwcGxpY2F0aW9uQ2FjaGVFcnJvckV2ZW50OlcuZWEsQmFj
+a2dyb3VuZEZldGNoQ2xpY2tFdmVudDpXLmVhLEJhY2tncm91bmRGZXRjaEV2ZW50OlcuZWEsQmFja2dy
+b3VuZEZldGNoRmFpbEV2ZW50OlcuZWEsQmFja2dyb3VuZEZldGNoZWRFdmVudDpXLmVhLEJlZm9yZUlu
+c3RhbGxQcm9tcHRFdmVudDpXLmVhLEJlZm9yZVVubG9hZEV2ZW50OlcuZWEsQmxvYkV2ZW50OlcuZWEs
+Q2FuTWFrZVBheW1lbnRFdmVudDpXLmVhLENsaXBib2FyZEV2ZW50OlcuZWEsQ2xvc2VFdmVudDpXLmVh
+LEN1c3RvbUV2ZW50OlcuZWEsRGV2aWNlTW90aW9uRXZlbnQ6Vy5lYSxEZXZpY2VPcmllbnRhdGlvbkV2
+ZW50OlcuZWEsRXJyb3JFdmVudDpXLmVhLEV4dGVuZGFibGVFdmVudDpXLmVhLEV4dGVuZGFibGVNZXNz
+YWdlRXZlbnQ6Vy5lYSxGZXRjaEV2ZW50OlcuZWEsRm9udEZhY2VTZXRMb2FkRXZlbnQ6Vy5lYSxGb3Jl
+aWduRmV0Y2hFdmVudDpXLmVhLEdhbWVwYWRFdmVudDpXLmVhLEhhc2hDaGFuZ2VFdmVudDpXLmVhLElu
+c3RhbGxFdmVudDpXLmVhLE1lZGlhRW5jcnlwdGVkRXZlbnQ6Vy5lYSxNZWRpYUtleU1lc3NhZ2VFdmVu
+dDpXLmVhLE1lZGlhUXVlcnlMaXN0RXZlbnQ6Vy5lYSxNZWRpYVN0cmVhbUV2ZW50OlcuZWEsTWVkaWFT
+dHJlYW1UcmFja0V2ZW50OlcuZWEsTWVzc2FnZUV2ZW50OlcuZWEsTUlESUNvbm5lY3Rpb25FdmVudDpX
+LmVhLE1JRElNZXNzYWdlRXZlbnQ6Vy5lYSxNdXRhdGlvbkV2ZW50OlcuZWEsTm90aWZpY2F0aW9uRXZl
+bnQ6Vy5lYSxQYWdlVHJhbnNpdGlvbkV2ZW50OlcuZWEsUGF5bWVudFJlcXVlc3RFdmVudDpXLmVhLFBh
+eW1lbnRSZXF1ZXN0VXBkYXRlRXZlbnQ6Vy5lYSxQb3BTdGF0ZUV2ZW50OlcuZWEsUHJlc2VudGF0aW9u
+Q29ubmVjdGlvbkF2YWlsYWJsZUV2ZW50OlcuZWEsUHJlc2VudGF0aW9uQ29ubmVjdGlvbkNsb3NlRXZl
+bnQ6Vy5lYSxQcm9taXNlUmVqZWN0aW9uRXZlbnQ6Vy5lYSxQdXNoRXZlbnQ6Vy5lYSxSVENEYXRhQ2hh
+bm5lbEV2ZW50OlcuZWEsUlRDRFRNRlRvbmVDaGFuZ2VFdmVudDpXLmVhLFJUQ1BlZXJDb25uZWN0aW9u
+SWNlRXZlbnQ6Vy5lYSxSVENUcmFja0V2ZW50OlcuZWEsU2VjdXJpdHlQb2xpY3lWaW9sYXRpb25FdmVu
+dDpXLmVhLFNlbnNvckVycm9yRXZlbnQ6Vy5lYSxTcGVlY2hSZWNvZ25pdGlvbkVycm9yOlcuZWEsU3Bl
+ZWNoUmVjb2duaXRpb25FdmVudDpXLmVhLFNwZWVjaFN5bnRoZXNpc0V2ZW50OlcuZWEsU3RvcmFnZUV2
+ZW50OlcuZWEsU3luY0V2ZW50OlcuZWEsVHJhY2tFdmVudDpXLmVhLFRyYW5zaXRpb25FdmVudDpXLmVh
+LFdlYktpdFRyYW5zaXRpb25FdmVudDpXLmVhLFZSRGV2aWNlRXZlbnQ6Vy5lYSxWUkRpc3BsYXlFdmVu
+dDpXLmVhLFZSU2Vzc2lvbkV2ZW50OlcuZWEsTW9qb0ludGVyZmFjZVJlcXVlc3RFdmVudDpXLmVhLFVT
+QkNvbm5lY3Rpb25FdmVudDpXLmVhLElEQlZlcnNpb25DaGFuZ2VFdmVudDpXLmVhLEF1ZGlvUHJvY2Vz
+c2luZ0V2ZW50OlcuZWEsT2ZmbGluZUF1ZGlvQ29tcGxldGlvbkV2ZW50OlcuZWEsV2ViR0xDb250ZXh0
+RXZlbnQ6Vy5lYSxFdmVudDpXLmVhLElucHV0RXZlbnQ6Vy5lYSxTdWJtaXRFdmVudDpXLmVhLEV2ZW50
+VGFyZ2V0OlcuRDAsRmlsZTpXLlQ1LEhUTUxGb3JtRWxlbWVudDpXLmg0LEhpc3Rvcnk6Vy5icixIVE1M
+RG9jdW1lbnQ6Vy5WYixYTUxIdHRwUmVxdWVzdDpXLmZKLFhNTEh0dHBSZXF1ZXN0RXZlbnRUYXJnZXQ6
+Vy53YSxJbWFnZURhdGE6Vy5TZyxMb2NhdGlvbjpXLnU4LE1vdXNlRXZlbnQ6Vy5PSyxEcmFnRXZlbnQ6
+Vy5PSyxQb2ludGVyRXZlbnQ6Vy5PSyxXaGVlbEV2ZW50OlcuT0ssRG9jdW1lbnRGcmFnbWVudDpXLnVI
+LFNoYWRvd1Jvb3Q6Vy51SCxEb2N1bWVudFR5cGU6Vy51SCxOb2RlOlcudUgsTm9kZUxpc3Q6Vy5CSCxS
+YWRpb05vZGVMaXN0OlcuQkgsSFRNTFBhcmFncmFwaEVsZW1lbnQ6Vy5TTixQcm9ncmVzc0V2ZW50Olcu
+ZXcsUmVzb3VyY2VQcm9ncmVzc0V2ZW50OlcuZXcsSFRNTFNlbGVjdEVsZW1lbnQ6Vy5scCxIVE1MVGFi
+bGVFbGVtZW50OlcuVGIsSFRNTFRhYmxlUm93RWxlbWVudDpXLkl2LEhUTUxUYWJsZVNlY3Rpb25FbGVt
+ZW50OlcuV1AsSFRNTFRlbXBsYXRlRWxlbWVudDpXLnlZLENvbXBvc2l0aW9uRXZlbnQ6Vy53NixGb2N1
+c0V2ZW50OlcudzYsS2V5Ym9hcmRFdmVudDpXLnc2LFRleHRFdmVudDpXLnc2LFRvdWNoRXZlbnQ6Vy53
+NixVSUV2ZW50OlcudzYsV2luZG93OlcuSzUsRE9NV2luZG93OlcuSzUsRGVkaWNhdGVkV29ya2VyR2xv
+YmFsU2NvcGU6Vy5DbSxTZXJ2aWNlV29ya2VyR2xvYmFsU2NvcGU6Vy5DbSxTaGFyZWRXb3JrZXJHbG9i
+YWxTY29wZTpXLkNtLFdvcmtlckdsb2JhbFNjb3BlOlcuQ20sQXR0cjpXLkNRLENsaWVudFJlY3Q6Vy53
+NCxET01SZWN0OlcudzQsTmFtZWROb2RlTWFwOlcucmgsTW96TmFtZWRBdHRyTWFwOlcucmgsSURCS2V5
+UmFuZ2U6UC5oRixTVkdTY3JpcHRFbGVtZW50OlAuYkIsU1ZHQUVsZW1lbnQ6UC5kNSxTVkdBbmltYXRl
+RWxlbWVudDpQLmQ1LFNWR0FuaW1hdGVNb3Rpb25FbGVtZW50OlAuZDUsU1ZHQW5pbWF0ZVRyYW5zZm9y
+bUVsZW1lbnQ6UC5kNSxTVkdBbmltYXRpb25FbGVtZW50OlAuZDUsU1ZHQ2lyY2xlRWxlbWVudDpQLmQ1
+LFNWR0NsaXBQYXRoRWxlbWVudDpQLmQ1LFNWR0RlZnNFbGVtZW50OlAuZDUsU1ZHRGVzY0VsZW1lbnQ6
+UC5kNSxTVkdEaXNjYXJkRWxlbWVudDpQLmQ1LFNWR0VsbGlwc2VFbGVtZW50OlAuZDUsU1ZHRkVCbGVu
+ZEVsZW1lbnQ6UC5kNSxTVkdGRUNvbG9yTWF0cml4RWxlbWVudDpQLmQ1LFNWR0ZFQ29tcG9uZW50VHJh
+bnNmZXJFbGVtZW50OlAuZDUsU1ZHRkVDb21wb3NpdGVFbGVtZW50OlAuZDUsU1ZHRkVDb252b2x2ZU1h
+dHJpeEVsZW1lbnQ6UC5kNSxTVkdGRURpZmZ1c2VMaWdodGluZ0VsZW1lbnQ6UC5kNSxTVkdGRURpc3Bs
+YWNlbWVudE1hcEVsZW1lbnQ6UC5kNSxTVkdGRURpc3RhbnRMaWdodEVsZW1lbnQ6UC5kNSxTVkdGRUZs
+b29kRWxlbWVudDpQLmQ1LFNWR0ZFRnVuY0FFbGVtZW50OlAuZDUsU1ZHRkVGdW5jQkVsZW1lbnQ6UC5k
+NSxTVkdGRUZ1bmNHRWxlbWVudDpQLmQ1LFNWR0ZFRnVuY1JFbGVtZW50OlAuZDUsU1ZHRkVHYXVzc2lh
+bkJsdXJFbGVtZW50OlAuZDUsU1ZHRkVJbWFnZUVsZW1lbnQ6UC5kNSxTVkdGRU1lcmdlRWxlbWVudDpQ
+LmQ1LFNWR0ZFTWVyZ2VOb2RlRWxlbWVudDpQLmQ1LFNWR0ZFTW9ycGhvbG9neUVsZW1lbnQ6UC5kNSxT
+VkdGRU9mZnNldEVsZW1lbnQ6UC5kNSxTVkdGRVBvaW50TGlnaHRFbGVtZW50OlAuZDUsU1ZHRkVTcGVj
+dWxhckxpZ2h0aW5nRWxlbWVudDpQLmQ1LFNWR0ZFU3BvdExpZ2h0RWxlbWVudDpQLmQ1LFNWR0ZFVGls
+ZUVsZW1lbnQ6UC5kNSxTVkdGRVR1cmJ1bGVuY2VFbGVtZW50OlAuZDUsU1ZHRmlsdGVyRWxlbWVudDpQ
+LmQ1LFNWR0ZvcmVpZ25PYmplY3RFbGVtZW50OlAuZDUsU1ZHR0VsZW1lbnQ6UC5kNSxTVkdHZW9tZXRy
+eUVsZW1lbnQ6UC5kNSxTVkdHcmFwaGljc0VsZW1lbnQ6UC5kNSxTVkdJbWFnZUVsZW1lbnQ6UC5kNSxT
+VkdMaW5lRWxlbWVudDpQLmQ1LFNWR0xpbmVhckdyYWRpZW50RWxlbWVudDpQLmQ1LFNWR01hcmtlckVs
+ZW1lbnQ6UC5kNSxTVkdNYXNrRWxlbWVudDpQLmQ1LFNWR01ldGFkYXRhRWxlbWVudDpQLmQ1LFNWR1Bh
+dGhFbGVtZW50OlAuZDUsU1ZHUGF0dGVybkVsZW1lbnQ6UC5kNSxTVkdQb2x5Z29uRWxlbWVudDpQLmQ1
+LFNWR1BvbHlsaW5lRWxlbWVudDpQLmQ1LFNWR1JhZGlhbEdyYWRpZW50RWxlbWVudDpQLmQ1LFNWR1Jl
+Y3RFbGVtZW50OlAuZDUsU1ZHU2V0RWxlbWVudDpQLmQ1LFNWR1N0b3BFbGVtZW50OlAuZDUsU1ZHU3R5
+bGVFbGVtZW50OlAuZDUsU1ZHU1ZHRWxlbWVudDpQLmQ1LFNWR1N3aXRjaEVsZW1lbnQ6UC5kNSxTVkdT
+eW1ib2xFbGVtZW50OlAuZDUsU1ZHVFNwYW5FbGVtZW50OlAuZDUsU1ZHVGV4dENvbnRlbnRFbGVtZW50
+OlAuZDUsU1ZHVGV4dEVsZW1lbnQ6UC5kNSxTVkdUZXh0UGF0aEVsZW1lbnQ6UC5kNSxTVkdUZXh0UG9z
+aXRpb25pbmdFbGVtZW50OlAuZDUsU1ZHVGl0bGVFbGVtZW50OlAuZDUsU1ZHVXNlRWxlbWVudDpQLmQ1
+LFNWR1ZpZXdFbGVtZW50OlAuZDUsU1ZHR3JhZGllbnRFbGVtZW50OlAuZDUsU1ZHQ29tcG9uZW50VHJh
+bnNmZXJGdW5jdGlvbkVsZW1lbnQ6UC5kNSxTVkdGRURyb3BTaGFkb3dFbGVtZW50OlAuZDUsU1ZHTVBh
+dGhFbGVtZW50OlAuZDUsU1ZHRWxlbWVudDpQLmQ1fSkKaHVua0hlbHBlcnMuc2V0T3JVcGRhdGVMZWFm
+VGFncyh7RE9NRXJyb3I6dHJ1ZSxNZWRpYUVycm9yOnRydWUsTmF2aWdhdG9yOnRydWUsTmF2aWdhdG9y
+Q29uY3VycmVudEhhcmR3YXJlOnRydWUsTmF2aWdhdG9yVXNlck1lZGlhRXJyb3I6dHJ1ZSxPdmVyY29u
+c3RyYWluZWRFcnJvcjp0cnVlLFBvc2l0aW9uRXJyb3I6dHJ1ZSxSYW5nZTp0cnVlLFNRTEVycm9yOnRy
+dWUsRGF0YVZpZXc6dHJ1ZSxBcnJheUJ1ZmZlclZpZXc6ZmFsc2UsRmxvYXQzMkFycmF5OnRydWUsRmxv
+YXQ2NEFycmF5OnRydWUsSW50MTZBcnJheTp0cnVlLEludDMyQXJyYXk6dHJ1ZSxJbnQ4QXJyYXk6dHJ1
+ZSxVaW50MTZBcnJheTp0cnVlLFVpbnQzMkFycmF5OnRydWUsVWludDhDbGFtcGVkQXJyYXk6dHJ1ZSxD
+YW52YXNQaXhlbEFycmF5OnRydWUsVWludDhBcnJheTpmYWxzZSxIVE1MQXVkaW9FbGVtZW50OnRydWUs
+SFRNTEJSRWxlbWVudDp0cnVlLEhUTUxCdXR0b25FbGVtZW50OnRydWUsSFRNTENhbnZhc0VsZW1lbnQ6
+dHJ1ZSxIVE1MQ29udGVudEVsZW1lbnQ6dHJ1ZSxIVE1MRExpc3RFbGVtZW50OnRydWUsSFRNTERhdGFF
+bGVtZW50OnRydWUsSFRNTERhdGFMaXN0RWxlbWVudDp0cnVlLEhUTUxEZXRhaWxzRWxlbWVudDp0cnVl
+LEhUTUxEaWFsb2dFbGVtZW50OnRydWUsSFRNTERpdkVsZW1lbnQ6dHJ1ZSxIVE1MRW1iZWRFbGVtZW50
+OnRydWUsSFRNTEZpZWxkU2V0RWxlbWVudDp0cnVlLEhUTUxIUkVsZW1lbnQ6dHJ1ZSxIVE1MSGVhZEVs
+ZW1lbnQ6dHJ1ZSxIVE1MSGVhZGluZ0VsZW1lbnQ6dHJ1ZSxIVE1MSHRtbEVsZW1lbnQ6dHJ1ZSxIVE1M
+SUZyYW1lRWxlbWVudDp0cnVlLEhUTUxJbWFnZUVsZW1lbnQ6dHJ1ZSxIVE1MSW5wdXRFbGVtZW50OnRy
+dWUsSFRNTExJRWxlbWVudDp0cnVlLEhUTUxMYWJlbEVsZW1lbnQ6dHJ1ZSxIVE1MTGVnZW5kRWxlbWVu
+dDp0cnVlLEhUTUxMaW5rRWxlbWVudDp0cnVlLEhUTUxNYXBFbGVtZW50OnRydWUsSFRNTE1lZGlhRWxl
+bWVudDp0cnVlLEhUTUxNZW51RWxlbWVudDp0cnVlLEhUTUxNZXRhRWxlbWVudDp0cnVlLEhUTUxNZXRl
+ckVsZW1lbnQ6dHJ1ZSxIVE1MTW9kRWxlbWVudDp0cnVlLEhUTUxPTGlzdEVsZW1lbnQ6dHJ1ZSxIVE1M
+T2JqZWN0RWxlbWVudDp0cnVlLEhUTUxPcHRHcm91cEVsZW1lbnQ6dHJ1ZSxIVE1MT3B0aW9uRWxlbWVu
+dDp0cnVlLEhUTUxPdXRwdXRFbGVtZW50OnRydWUsSFRNTFBhcmFtRWxlbWVudDp0cnVlLEhUTUxQaWN0
+dXJlRWxlbWVudDp0cnVlLEhUTUxQcmVFbGVtZW50OnRydWUsSFRNTFByb2dyZXNzRWxlbWVudDp0cnVl
+LEhUTUxRdW90ZUVsZW1lbnQ6dHJ1ZSxIVE1MU2NyaXB0RWxlbWVudDp0cnVlLEhUTUxTaGFkb3dFbGVt
+ZW50OnRydWUsSFRNTFNsb3RFbGVtZW50OnRydWUsSFRNTFNvdXJjZUVsZW1lbnQ6dHJ1ZSxIVE1MU3Bh
+bkVsZW1lbnQ6dHJ1ZSxIVE1MU3R5bGVFbGVtZW50OnRydWUsSFRNTFRhYmxlQ2FwdGlvbkVsZW1lbnQ6
+dHJ1ZSxIVE1MVGFibGVDZWxsRWxlbWVudDp0cnVlLEhUTUxUYWJsZURhdGFDZWxsRWxlbWVudDp0cnVl
+LEhUTUxUYWJsZUhlYWRlckNlbGxFbGVtZW50OnRydWUsSFRNTFRhYmxlQ29sRWxlbWVudDp0cnVlLEhU
+TUxUZXh0QXJlYUVsZW1lbnQ6dHJ1ZSxIVE1MVGltZUVsZW1lbnQ6dHJ1ZSxIVE1MVGl0bGVFbGVtZW50
+OnRydWUsSFRNTFRyYWNrRWxlbWVudDp0cnVlLEhUTUxVTGlzdEVsZW1lbnQ6dHJ1ZSxIVE1MVW5rbm93
+bkVsZW1lbnQ6dHJ1ZSxIVE1MVmlkZW9FbGVtZW50OnRydWUsSFRNTERpcmVjdG9yeUVsZW1lbnQ6dHJ1
+ZSxIVE1MRm9udEVsZW1lbnQ6dHJ1ZSxIVE1MRnJhbWVFbGVtZW50OnRydWUsSFRNTEZyYW1lU2V0RWxl
+bWVudDp0cnVlLEhUTUxNYXJxdWVlRWxlbWVudDp0cnVlLEhUTUxFbGVtZW50OmZhbHNlLEhUTUxBbmNo
+b3JFbGVtZW50OnRydWUsSFRNTEFyZWFFbGVtZW50OnRydWUsSFRNTEJhc2VFbGVtZW50OnRydWUsQmxv
+YjpmYWxzZSxIVE1MQm9keUVsZW1lbnQ6dHJ1ZSxDREFUQVNlY3Rpb246dHJ1ZSxDaGFyYWN0ZXJEYXRh
+OnRydWUsQ29tbWVudDp0cnVlLFByb2Nlc3NpbmdJbnN0cnVjdGlvbjp0cnVlLFRleHQ6dHJ1ZSxDU1NT
+dHlsZURlY2xhcmF0aW9uOnRydWUsTVNTdHlsZUNTU1Byb3BlcnRpZXM6dHJ1ZSxDU1MyUHJvcGVydGll
+czp0cnVlLFhNTERvY3VtZW50OnRydWUsRG9jdW1lbnQ6ZmFsc2UsRE9NRXhjZXB0aW9uOnRydWUsRE9N
+SW1wbGVtZW50YXRpb246dHJ1ZSxET01SZWN0UmVhZE9ubHk6ZmFsc2UsRE9NVG9rZW5MaXN0OnRydWUs
+RWxlbWVudDpmYWxzZSxBYm9ydFBheW1lbnRFdmVudDp0cnVlLEFuaW1hdGlvbkV2ZW50OnRydWUsQW5p
+bWF0aW9uUGxheWJhY2tFdmVudDp0cnVlLEFwcGxpY2F0aW9uQ2FjaGVFcnJvckV2ZW50OnRydWUsQmFj
+a2dyb3VuZEZldGNoQ2xpY2tFdmVudDp0cnVlLEJhY2tncm91bmRGZXRjaEV2ZW50OnRydWUsQmFja2dy
+b3VuZEZldGNoRmFpbEV2ZW50OnRydWUsQmFja2dyb3VuZEZldGNoZWRFdmVudDp0cnVlLEJlZm9yZUlu
+c3RhbGxQcm9tcHRFdmVudDp0cnVlLEJlZm9yZVVubG9hZEV2ZW50OnRydWUsQmxvYkV2ZW50OnRydWUs
+Q2FuTWFrZVBheW1lbnRFdmVudDp0cnVlLENsaXBib2FyZEV2ZW50OnRydWUsQ2xvc2VFdmVudDp0cnVl
+LEN1c3RvbUV2ZW50OnRydWUsRGV2aWNlTW90aW9uRXZlbnQ6dHJ1ZSxEZXZpY2VPcmllbnRhdGlvbkV2
+ZW50OnRydWUsRXJyb3JFdmVudDp0cnVlLEV4dGVuZGFibGVFdmVudDp0cnVlLEV4dGVuZGFibGVNZXNz
+YWdlRXZlbnQ6dHJ1ZSxGZXRjaEV2ZW50OnRydWUsRm9udEZhY2VTZXRMb2FkRXZlbnQ6dHJ1ZSxGb3Jl
+aWduRmV0Y2hFdmVudDp0cnVlLEdhbWVwYWRFdmVudDp0cnVlLEhhc2hDaGFuZ2VFdmVudDp0cnVlLElu
+c3RhbGxFdmVudDp0cnVlLE1lZGlhRW5jcnlwdGVkRXZlbnQ6dHJ1ZSxNZWRpYUtleU1lc3NhZ2VFdmVu
+dDp0cnVlLE1lZGlhUXVlcnlMaXN0RXZlbnQ6dHJ1ZSxNZWRpYVN0cmVhbUV2ZW50OnRydWUsTWVkaWFT
+dHJlYW1UcmFja0V2ZW50OnRydWUsTWVzc2FnZUV2ZW50OnRydWUsTUlESUNvbm5lY3Rpb25FdmVudDp0
+cnVlLE1JRElNZXNzYWdlRXZlbnQ6dHJ1ZSxNdXRhdGlvbkV2ZW50OnRydWUsTm90aWZpY2F0aW9uRXZl
+bnQ6dHJ1ZSxQYWdlVHJhbnNpdGlvbkV2ZW50OnRydWUsUGF5bWVudFJlcXVlc3RFdmVudDp0cnVlLFBh
+eW1lbnRSZXF1ZXN0VXBkYXRlRXZlbnQ6dHJ1ZSxQb3BTdGF0ZUV2ZW50OnRydWUsUHJlc2VudGF0aW9u
+Q29ubmVjdGlvbkF2YWlsYWJsZUV2ZW50OnRydWUsUHJlc2VudGF0aW9uQ29ubmVjdGlvbkNsb3NlRXZl
+bnQ6dHJ1ZSxQcm9taXNlUmVqZWN0aW9uRXZlbnQ6dHJ1ZSxQdXNoRXZlbnQ6dHJ1ZSxSVENEYXRhQ2hh
+bm5lbEV2ZW50OnRydWUsUlRDRFRNRlRvbmVDaGFuZ2VFdmVudDp0cnVlLFJUQ1BlZXJDb25uZWN0aW9u
+SWNlRXZlbnQ6dHJ1ZSxSVENUcmFja0V2ZW50OnRydWUsU2VjdXJpdHlQb2xpY3lWaW9sYXRpb25FdmVu
+dDp0cnVlLFNlbnNvckVycm9yRXZlbnQ6dHJ1ZSxTcGVlY2hSZWNvZ25pdGlvbkVycm9yOnRydWUsU3Bl
+ZWNoUmVjb2duaXRpb25FdmVudDp0cnVlLFNwZWVjaFN5bnRoZXNpc0V2ZW50OnRydWUsU3RvcmFnZUV2
+ZW50OnRydWUsU3luY0V2ZW50OnRydWUsVHJhY2tFdmVudDp0cnVlLFRyYW5zaXRpb25FdmVudDp0cnVl
+LFdlYktpdFRyYW5zaXRpb25FdmVudDp0cnVlLFZSRGV2aWNlRXZlbnQ6dHJ1ZSxWUkRpc3BsYXlFdmVu
+dDp0cnVlLFZSU2Vzc2lvbkV2ZW50OnRydWUsTW9qb0ludGVyZmFjZVJlcXVlc3RFdmVudDp0cnVlLFVT
+QkNvbm5lY3Rpb25FdmVudDp0cnVlLElEQlZlcnNpb25DaGFuZ2VFdmVudDp0cnVlLEF1ZGlvUHJvY2Vz
+c2luZ0V2ZW50OnRydWUsT2ZmbGluZUF1ZGlvQ29tcGxldGlvbkV2ZW50OnRydWUsV2ViR0xDb250ZXh0
+RXZlbnQ6dHJ1ZSxFdmVudDpmYWxzZSxJbnB1dEV2ZW50OmZhbHNlLFN1Ym1pdEV2ZW50OmZhbHNlLEV2
+ZW50VGFyZ2V0OmZhbHNlLEZpbGU6dHJ1ZSxIVE1MRm9ybUVsZW1lbnQ6dHJ1ZSxIaXN0b3J5OnRydWUs
+SFRNTERvY3VtZW50OnRydWUsWE1MSHR0cFJlcXVlc3Q6dHJ1ZSxYTUxIdHRwUmVxdWVzdEV2ZW50VGFy
+Z2V0OmZhbHNlLEltYWdlRGF0YTp0cnVlLExvY2F0aW9uOnRydWUsTW91c2VFdmVudDp0cnVlLERyYWdF
+dmVudDp0cnVlLFBvaW50ZXJFdmVudDp0cnVlLFdoZWVsRXZlbnQ6dHJ1ZSxEb2N1bWVudEZyYWdtZW50
+OnRydWUsU2hhZG93Um9vdDp0cnVlLERvY3VtZW50VHlwZTp0cnVlLE5vZGU6ZmFsc2UsTm9kZUxpc3Q6
+dHJ1ZSxSYWRpb05vZGVMaXN0OnRydWUsSFRNTFBhcmFncmFwaEVsZW1lbnQ6dHJ1ZSxQcm9ncmVzc0V2
+ZW50OnRydWUsUmVzb3VyY2VQcm9ncmVzc0V2ZW50OnRydWUsSFRNTFNlbGVjdEVsZW1lbnQ6dHJ1ZSxI
+VE1MVGFibGVFbGVtZW50OnRydWUsSFRNTFRhYmxlUm93RWxlbWVudDp0cnVlLEhUTUxUYWJsZVNlY3Rp
+b25FbGVtZW50OnRydWUsSFRNTFRlbXBsYXRlRWxlbWVudDp0cnVlLENvbXBvc2l0aW9uRXZlbnQ6dHJ1
+ZSxGb2N1c0V2ZW50OnRydWUsS2V5Ym9hcmRFdmVudDp0cnVlLFRleHRFdmVudDp0cnVlLFRvdWNoRXZl
+bnQ6dHJ1ZSxVSUV2ZW50OmZhbHNlLFdpbmRvdzp0cnVlLERPTVdpbmRvdzp0cnVlLERlZGljYXRlZFdv
+cmtlckdsb2JhbFNjb3BlOnRydWUsU2VydmljZVdvcmtlckdsb2JhbFNjb3BlOnRydWUsU2hhcmVkV29y
+a2VyR2xvYmFsU2NvcGU6dHJ1ZSxXb3JrZXJHbG9iYWxTY29wZTp0cnVlLEF0dHI6dHJ1ZSxDbGllbnRS
+ZWN0OnRydWUsRE9NUmVjdDp0cnVlLE5hbWVkTm9kZU1hcDp0cnVlLE1vek5hbWVkQXR0ck1hcDp0cnVl
+LElEQktleVJhbmdlOnRydWUsU1ZHU2NyaXB0RWxlbWVudDp0cnVlLFNWR0FFbGVtZW50OnRydWUsU1ZH
+QW5pbWF0ZUVsZW1lbnQ6dHJ1ZSxTVkdBbmltYXRlTW90aW9uRWxlbWVudDp0cnVlLFNWR0FuaW1hdGVU
+cmFuc2Zvcm1FbGVtZW50OnRydWUsU1ZHQW5pbWF0aW9uRWxlbWVudDp0cnVlLFNWR0NpcmNsZUVsZW1l
+bnQ6dHJ1ZSxTVkdDbGlwUGF0aEVsZW1lbnQ6dHJ1ZSxTVkdEZWZzRWxlbWVudDp0cnVlLFNWR0Rlc2NF
+bGVtZW50OnRydWUsU1ZHRGlzY2FyZEVsZW1lbnQ6dHJ1ZSxTVkdFbGxpcHNlRWxlbWVudDp0cnVlLFNW
+R0ZFQmxlbmRFbGVtZW50OnRydWUsU1ZHRkVDb2xvck1hdHJpeEVsZW1lbnQ6dHJ1ZSxTVkdGRUNvbXBv
+bmVudFRyYW5zZmVyRWxlbWVudDp0cnVlLFNWR0ZFQ29tcG9zaXRlRWxlbWVudDp0cnVlLFNWR0ZFQ29u
+dm9sdmVNYXRyaXhFbGVtZW50OnRydWUsU1ZHRkVEaWZmdXNlTGlnaHRpbmdFbGVtZW50OnRydWUsU1ZH
+RkVEaXNwbGFjZW1lbnRNYXBFbGVtZW50OnRydWUsU1ZHRkVEaXN0YW50TGlnaHRFbGVtZW50OnRydWUs
+U1ZHRkVGbG9vZEVsZW1lbnQ6dHJ1ZSxTVkdGRUZ1bmNBRWxlbWVudDp0cnVlLFNWR0ZFRnVuY0JFbGVt
+ZW50OnRydWUsU1ZHRkVGdW5jR0VsZW1lbnQ6dHJ1ZSxTVkdGRUZ1bmNSRWxlbWVudDp0cnVlLFNWR0ZF
+R2F1c3NpYW5CbHVyRWxlbWVudDp0cnVlLFNWR0ZFSW1hZ2VFbGVtZW50OnRydWUsU1ZHRkVNZXJnZUVs
+ZW1lbnQ6dHJ1ZSxTVkdGRU1lcmdlTm9kZUVsZW1lbnQ6dHJ1ZSxTVkdGRU1vcnBob2xvZ3lFbGVtZW50
+OnRydWUsU1ZHRkVPZmZzZXRFbGVtZW50OnRydWUsU1ZHRkVQb2ludExpZ2h0RWxlbWVudDp0cnVlLFNW
+R0ZFU3BlY3VsYXJMaWdodGluZ0VsZW1lbnQ6dHJ1ZSxTVkdGRVNwb3RMaWdodEVsZW1lbnQ6dHJ1ZSxT
+VkdGRVRpbGVFbGVtZW50OnRydWUsU1ZHRkVUdXJidWxlbmNlRWxlbWVudDp0cnVlLFNWR0ZpbHRlckVs
+ZW1lbnQ6dHJ1ZSxTVkdGb3JlaWduT2JqZWN0RWxlbWVudDp0cnVlLFNWR0dFbGVtZW50OnRydWUsU1ZH
+R2VvbWV0cnlFbGVtZW50OnRydWUsU1ZHR3JhcGhpY3NFbGVtZW50OnRydWUsU1ZHSW1hZ2VFbGVtZW50
+OnRydWUsU1ZHTGluZUVsZW1lbnQ6dHJ1ZSxTVkdMaW5lYXJHcmFkaWVudEVsZW1lbnQ6dHJ1ZSxTVkdN
+YXJrZXJFbGVtZW50OnRydWUsU1ZHTWFza0VsZW1lbnQ6dHJ1ZSxTVkdNZXRhZGF0YUVsZW1lbnQ6dHJ1
+ZSxTVkdQYXRoRWxlbWVudDp0cnVlLFNWR1BhdHRlcm5FbGVtZW50OnRydWUsU1ZHUG9seWdvbkVsZW1l
+bnQ6dHJ1ZSxTVkdQb2x5bGluZUVsZW1lbnQ6dHJ1ZSxTVkdSYWRpYWxHcmFkaWVudEVsZW1lbnQ6dHJ1
+ZSxTVkdSZWN0RWxlbWVudDp0cnVlLFNWR1NldEVsZW1lbnQ6dHJ1ZSxTVkdTdG9wRWxlbWVudDp0cnVl
+LFNWR1N0eWxlRWxlbWVudDp0cnVlLFNWR1NWR0VsZW1lbnQ6dHJ1ZSxTVkdTd2l0Y2hFbGVtZW50OnRy
+dWUsU1ZHU3ltYm9sRWxlbWVudDp0cnVlLFNWR1RTcGFuRWxlbWVudDp0cnVlLFNWR1RleHRDb250ZW50
+RWxlbWVudDp0cnVlLFNWR1RleHRFbGVtZW50OnRydWUsU1ZHVGV4dFBhdGhFbGVtZW50OnRydWUsU1ZH
+VGV4dFBvc2l0aW9uaW5nRWxlbWVudDp0cnVlLFNWR1RpdGxlRWxlbWVudDp0cnVlLFNWR1VzZUVsZW1l
+bnQ6dHJ1ZSxTVkdWaWV3RWxlbWVudDp0cnVlLFNWR0dyYWRpZW50RWxlbWVudDp0cnVlLFNWR0NvbXBv
+bmVudFRyYW5zZmVyRnVuY3Rpb25FbGVtZW50OnRydWUsU1ZHRkVEcm9wU2hhZG93RWxlbWVudDp0cnVl
+LFNWR01QYXRoRWxlbWVudDp0cnVlLFNWR0VsZW1lbnQ6ZmFsc2V9KQpILmIwLiRuYXRpdmVTdXBlcmNs
+YXNzVGFnPSJBcnJheUJ1ZmZlclZpZXciCkguUkcuJG5hdGl2ZVN1cGVyY2xhc3NUYWc9IkFycmF5QnVm
+ZmVyVmlldyIKSC5WUC4kbmF0aXZlU3VwZXJjbGFzc1RhZz0iQXJyYXlCdWZmZXJWaWV3IgpILkRnLiRu
+YXRpdmVTdXBlcmNsYXNzVGFnPSJBcnJheUJ1ZmZlclZpZXciCkguV0IuJG5hdGl2ZVN1cGVyY2xhc3NU
+YWc9IkFycmF5QnVmZmVyVmlldyIKSC5aRy4kbmF0aXZlU3VwZXJjbGFzc1RhZz0iQXJyYXlCdWZmZXJW
+aWV3IgpILlBnLiRuYXRpdmVTdXBlcmNsYXNzVGFnPSJBcnJheUJ1ZmZlclZpZXcifSkoKQpjb252ZXJ0
+QWxsVG9GYXN0T2JqZWN0KHcpCmNvbnZlcnRUb0Zhc3RPYmplY3QoJCk7KGZ1bmN0aW9uKGEpe2lmKHR5
+cGVvZiBkb2N1bWVudD09PSJ1bmRlZmluZWQiKXthKG51bGwpCnJldHVybn1pZih0eXBlb2YgZG9jdW1l
+bnQuY3VycmVudFNjcmlwdCE9J3VuZGVmaW5lZCcpe2EoZG9jdW1lbnQuY3VycmVudFNjcmlwdCkKcmV0
+dXJufXZhciB0PWRvY3VtZW50LnNjcmlwdHMKZnVuY3Rpb24gb25Mb2FkKGIpe2Zvcih2YXIgcj0wO3I8
+dC5sZW5ndGg7KytyKXRbcl0ucmVtb3ZlRXZlbnRMaXN0ZW5lcigibG9hZCIsb25Mb2FkLGZhbHNlKQph
+KGIudGFyZ2V0KX1mb3IodmFyIHM9MDtzPHQubGVuZ3RoOysrcyl0W3NdLmFkZEV2ZW50TGlzdGVuZXIo
+ImxvYWQiLG9uTG9hZCxmYWxzZSl9KShmdW5jdGlvbihhKXt2LmN1cnJlbnRTY3JpcHQ9YQppZih0eXBl
+b2YgZGFydE1haW5SdW5uZXI9PT0iZnVuY3Rpb24iKWRhcnRNYWluUnVubmVyKEwuSXEsW10pCmVsc2Ug
+TC5JcShbXSl9KX0pKCkKLy8jIHNvdXJjZU1hcHBpbmdVUkw9bWlncmF0aW9uLmpzLm1hcAo=
''';
diff --git a/pkg/nnbd_migration/lib/src/front_end/unit_renderer.dart b/pkg/nnbd_migration/lib/src/front_end/unit_renderer.dart
index 8e96fca..29aded6 100644
--- a/pkg/nnbd_migration/lib/src/front_end/unit_renderer.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/unit_renderer.dart
@@ -36,6 +36,7 @@
NullabilityFixKind.replaceVar,
NullabilityFixKind.removeAs,
NullabilityFixKind.addLate,
+ NullabilityFixKind.addLateDueToTestSetup,
NullabilityFixKind.addLateDueToHint,
NullabilityFixKind.checkExpressionDueToHint,
NullabilityFixKind.makeTypeNullableDueToHint,
@@ -250,6 +251,8 @@
return '$count late keyword$s added';
case NullabilityFixKind.addLateDueToHint:
return '$count late hint$s converted to late keyword$s';
+ case NullabilityFixKind.addLateDueToTestSetup:
+ return '$count late keyword$s added, due to assignment in `setUp`';
case NullabilityFixKind.addRequired:
return '$count required keyword$s added';
case NullabilityFixKind.addType:
diff --git a/pkg/nnbd_migration/lib/src/front_end/web/migration.dart b/pkg/nnbd_migration/lib/src/front_end/web/migration.dart
index 3447983..05ffafa 100644
--- a/pkg/nnbd_migration/lib/src/front_end/web/migration.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/web/migration.dart
@@ -260,7 +260,7 @@
(popupPane.querySelector('a.bottom') as AnchorElement).href =
getGithubUri(header, subheader, stackTrace).toString();
popupPane..style.display = 'initial';
- logError('handlePostLinkClick: $exception', stackTrace);
+ logError('$header: $exception', stackTrace);
}
void handleNavLinkClick(
diff --git a/pkg/nnbd_migration/lib/src/nullability_node.dart b/pkg/nnbd_migration/lib/src/nullability_node.dart
index 75e9e9b..8d803b5 100644
--- a/pkg/nnbd_migration/lib/src/nullability_node.dart
+++ b/pkg/nnbd_migration/lib/src/nullability_node.dart
@@ -9,6 +9,7 @@
import 'package:meta/meta.dart';
import 'package:nnbd_migration/instrumentation.dart';
import 'package:nnbd_migration/nullability_state.dart';
+import 'package:nnbd_migration/src/expression_checks.dart';
import 'package:nnbd_migration/src/nullability_node_target.dart';
import 'package:nnbd_migration/src/postmortem_file.dart';
@@ -59,6 +60,26 @@
: super.fromJson(json, deserializer);
}
+/// Conditions of the "lateness" of a [NullabilityNode].
+enum LateCondition {
+ /// The associated [NullabilityNode] does not represent the type of a late
+ /// variable.
+ notLate,
+
+ /// The associated [NullabilityNode] represents the type of a late variable,
+ /// due to a `/*late*/` hint.
+ lateDueToHint,
+
+ /// The associated [NullabilityNode] represents an variable which is possibly
+ /// late, due to the late-inferring algorithm.
+ possiblyLate,
+
+ /// The associated [NullabilityNode] represents an variable which is possibly
+ /// late, due to being assigned in a function passed to a call to the test
+ /// package's `setUp` function.
+ possiblyLateDueToTestSetup,
+}
+
/// Abstract interface for assigning ids numbers to nodes. This allows us to
/// annotate nodes with their ids when analyzing postmortem output.
abstract class NodeToIdMapper {
@@ -89,6 +110,10 @@
/// Whether this edge is the result of an uninitialized variable declaration.
final bool isUninit;
+ /// Whether this edge is the result of an assignment within the test package's
+ /// `setUp` function.
+ final bool isSetupAssignment;
+
NullabilityEdge.fromJson(
dynamic json, NullabilityGraphDeserializer deserializer)
: destinationNode = deserializer.nodeForId(json['dest'] as int),
@@ -97,7 +122,8 @@
codeReference =
json['code'] == null ? null : CodeReference.fromJson(json['code']),
description = json['description'] as String,
- isUninit = json['isUninit'] as bool {
+ isUninit = json['isUninit'] as bool,
+ isSetupAssignment = json['isSetupAssignment'] as bool {
deserializer.defer(() {
for (var id in json['us'] as List<dynamic>) {
upstreamNodes.add(deserializer.nodeForId(id as int));
@@ -107,7 +133,7 @@
NullabilityEdge._(
this.destinationNode, this.upstreamNodes, this._kind, this.description,
- {this.codeReference, this.isUninit});
+ {this.codeReference, this.isUninit, this.isSetupAssignment});
@override
Iterable<NullabilityNode> get guards => upstreamNodes.skip(1);
@@ -447,9 +473,13 @@
var isUninit = origin?.kind == EdgeOriginKind.fieldNotInitialized ||
origin?.kind == EdgeOriginKind.implicitNullInitializer ||
origin?.kind == EdgeOriginKind.uninitializedRead;
+ var isSetupAssignment =
+ origin is ExpressionChecksOrigin && origin.isSetupAssignment;
var edge = NullabilityEdge._(
destinationNode, upstreamNodes, kind, origin?.description,
- codeReference: origin?.codeReference, isUninit: isUninit);
+ codeReference: origin?.codeReference,
+ isUninit: isUninit,
+ isSetupAssignment: isSetupAssignment);
instrumentation?.graphEdge(edge, origin);
for (var upstreamNode in upstreamNodes) {
_connectDownstream(upstreamNode, edge);
@@ -673,7 +703,7 @@
/// variables. Over time this will be replaced by a first class representation
/// of the nullability inference graph.
abstract class NullabilityNode implements NullabilityNodeInfo {
- bool _isLate = false;
+ LateCondition _lateCondition = LateCondition.notLate;
bool _isPossiblyOptional = false;
@@ -776,10 +806,6 @@
@visibleForTesting
bool get isExactNullable;
- /// Indicates whether this node is associated with a variable declaration
- /// which should be annotated with "late".
- bool get isLate => _isLate;
-
/// After nullability propagation, this getter can be used to query whether
/// the type associated with this node should be considered nullable.
@override
@@ -789,6 +815,10 @@
/// nullability migration needs to decide whether it is optional or required.
bool get isPossiblyOptional => _isPossiblyOptional;
+ /// Indicates whether this node is associated with a variable declaration
+ /// which should be annotated with "late".
+ LateCondition get lateCondition => _lateCondition;
+
/// After nullability propagation, this getter can be used to query the node's
/// non-null intent state.
NonNullIntent get nonNullIntent;
@@ -1414,9 +1444,11 @@
continue;
}
}
- if (edge.isUninit) {
- // This is an edge from always to an uninitialized variable
+ if (edge.isUninit && !node.isNullable) {
+ // [edge] is an edge from always to an uninitialized variable
// declaration.
+ var isSetupAssigned = node.upstreamEdges
+ .any((e) => e is NullabilityEdge && e.isSetupAssignment);
// Whether all downstream edges go to nodes with non-null intent.
var allDownstreamHaveNonNullIntent = false;
@@ -1428,9 +1460,10 @@
});
}
if (allDownstreamHaveNonNullIntent) {
- if (!node.isNullable) {
- node._isLate = true;
- }
+ node._lateCondition = LateCondition.possiblyLate;
+ continue;
+ } else if (isSetupAssigned) {
+ node._lateCondition = LateCondition.possiblyLateDueToTestSetup;
continue;
}
}
@@ -1439,7 +1472,7 @@
step.targetNode = node;
step.newState = Nullability.ordinaryNullable;
_setNullable(step);
- node._isLate = false;
+ node._lateCondition = LateCondition.notLate;
}
}
if (_pendingSubstitutions.isEmpty) break;
diff --git a/pkg/nnbd_migration/lib/src/preview/preview_site.dart b/pkg/nnbd_migration/lib/src/preview/preview_site.dart
index 8d0b4f9..5e6190d 100644
--- a/pkg/nnbd_migration/lib/src/preview/preview_site.dart
+++ b/pkg/nnbd_migration/lib/src/preview/preview_site.dart
@@ -201,7 +201,9 @@
/// Perform the migration.
void performApply() {
if (migrationState.hasBeenApplied) {
- throw StateError('Cannot reapply migration.');
+ throw StateError(
+ 'It looks like this migration has already been applied. Try'
+ ' restarting the migration tool if this is not the case.');
}
final edits = migrationState.listener.sourceChange.edits;
@@ -214,7 +216,9 @@
}
var code = file.exists ? file.readAsStringSync() : '';
if (!unitInfoMap[file.path].hadDiskContent(code)) {
- throw StateError('${file.path} has changed, rerun migration to apply.');
+ throw StateError('Cannot apply migration. Files on disk do not match'
+ ' the expected pre-migration state. Press the "rerun from sources"'
+ ' button and then try again. (Changed file path is ${file.path})');
}
}
@@ -241,8 +245,9 @@
var file = pathMapper.provider.getFile(path);
var diskContent = file.readAsStringSync();
if (!unitInfoMap[path].hadDiskContent(diskContent)) {
- throw StateError(
- 'Cannot add hint, $path has changed. Rerun migration and try again.');
+ throw StateError('Cannot perform edit. This file has been changed since'
+ ' last migration run. Press the "rerun from sources" button and then'
+ ' try again. (Changed file path is ${file.path})');
}
final unitInfo = unitInfoMap[path];
final diskMapper = unitInfo.diskChangesOffsetMapper;
diff --git a/pkg/nnbd_migration/test/abstract_context.dart b/pkg/nnbd_migration/test/abstract_context.dart
index 645ca41..b1ffcc8 100644
--- a/pkg/nnbd_migration/test/abstract_context.dart
+++ b/pkg/nnbd_migration/test/abstract_context.dart
@@ -18,6 +18,9 @@
/// TODO(paulberry): this logic is duplicated from other packages. Find a way
/// share it, or avoid relying on it.
class AbstractContextTest with ResourceProviderMixin {
+ static const _homePath = '/home';
+ static const testsPath = '$_homePath/tests';
+
OverlayResourceProvider overlayResourceProvider;
AnalysisContextCollection _analysisContextCollection;
@@ -40,15 +43,27 @@
''');
}
- /// Add a new file with the given [pathInLib] to the package with the
- /// given [packageName]. Then ensure that the test package depends on the
- /// [packageName].
+ /// Add a new file with the given [pathInLib] to the package with the given
+ /// [packageName]. Then ensure that the package under test depends on the
+ /// package.
File addPackageFile(String packageName, String pathInLib, String content) {
var packagePath = '/.pub-cache/$packageName';
_addTestPackageDependency(packageName, packagePath);
return newFile('$packagePath/lib/$pathInLib', content: content);
}
+ /// Add the quiver package and a library with URI,
+ /// "package:quiver/check.dart".
+ ///
+ /// Then ensure that the package under test depends on the package.
+ void addQuiverPackage() {
+ addPackageFile('quiver', 'check.dart', r'''
+library quiver.check;
+
+T checkNotNull<T>(T reference, {dynamic message}) => T;
+''');
+ }
+
Source addSource(String path, String content, [Uri uri]) {
File file = newFile(path, content: content);
Source source = file.createSource(uri);
@@ -57,17 +72,34 @@
return source;
}
- /// Create all analysis contexts in `/home`.
+ /// Add the test_core package and a library with URI,
+ /// "package:test_core/test_core.dart".
+ ///
+ /// Then ensure that the package under test depends on the package.
+ void addTestCorePackage() {
+ addPackageFile('test_core', 'test_core.dart', r'''
+library test_core;
+
+void setUp(dynamic callback()) {}
+void group(dynamic description, dynamic body()) {}
+void test(dynamic description, dynamic body()) {}
+''');
+ addPackageFile('test', 'test.dart', r'''
+library test;
+export 'package:test_core/test_core.dart';
+''');
+ }
+
+ /// Create all analysis contexts in [_homePath].
void createAnalysisContexts() {
_analysisContextCollection = AnalysisContextCollectionImpl(
- includedPaths: [convertPath('/home')],
+ includedPaths: [convertPath(_homePath)],
enableIndex: true,
resourceProvider: overlayResourceProvider,
sdkPath: convertPath('/sdk'),
);
- var testPath = convertPath('/home/test');
- _driver = getDriver(testPath);
+ _driver = getDriver(convertPath(testsPath));
}
/// Return the existing analysis context that should be used to analyze the
@@ -93,9 +125,9 @@
new MockSdk(resourceProvider: resourceProvider);
- newFolder('/home/test');
- newFile('/home/test/.packages', content: r'''
-test:file:///home/test/lib
+ newFolder(testsPath);
+ newFile('$testsPath/.packages', content: '''
+tests:file://$testsPath/lib
''');
createAnalysisContexts();
@@ -108,7 +140,7 @@
}
void _addTestPackageDependency(String name, String rootPath) {
- var packagesFile = getFile('/home/test/.packages');
+ var packagesFile = getFile('$testsPath/.packages');
var packagesContent = packagesFile.readAsStringSync();
// Ignore if there is already the same package dependency.
@@ -125,13 +157,13 @@
void _createDriver() {
var collection = AnalysisContextCollectionImpl(
- includedPaths: [convertPath('/home')],
+ includedPaths: [convertPath(_homePath)],
enableIndex: true,
resourceProvider: resourceProvider,
sdkPath: convertPath('/sdk'),
);
- var testPath = convertPath('/home/test');
+ var testPath = convertPath(testsPath);
var context = collection.contextFor(testPath) as DriverBasedAnalysisContext;
_driver = context.driver;
diff --git a/pkg/nnbd_migration/test/abstract_single_unit.dart b/pkg/nnbd_migration/test/abstract_single_unit.dart
index 75a42a9..6c62f9e 100644
--- a/pkg/nnbd_migration/test/abstract_single_unit.dart
+++ b/pkg/nnbd_migration/test/abstract_single_unit.dart
@@ -65,7 +65,7 @@
@override
void setUp() {
- var testRoot = '/home/test';
+ var testRoot = AbstractContextTest.testsPath;
if (analyzeWithNnbd) {
newFile(convertPath('$testRoot/analysis_options.yaml'), content: '''
analyzer:
@@ -75,6 +75,6 @@
}
super.setUp();
testFile = convertPath('$testRoot/lib/test.dart');
- testUri = Uri.parse('package:test/test.dart');
+ testUri = Uri.parse('package:tests/test.dart');
}
}
diff --git a/pkg/nnbd_migration/test/api_test.dart b/pkg/nnbd_migration/test/api_test.dart
index 0a186f4..c13e7a8 100644
--- a/pkg/nnbd_migration/test/api_test.dart
+++ b/pkg/nnbd_migration/test/api_test.dart
@@ -239,6 +239,32 @@
await _checkSingleFileChanges(content, expected);
}
+ Future<void> test_argumentError_checkNotNull_implies_non_null_intent() async {
+ var content = '''
+void f(int i) {
+ ArgumentError.checkNotNull(i);
+}
+void g(bool b, int i) {
+ if (b) f(i);
+}
+main() {
+ g(false, null);
+}
+''';
+ var expected = '''
+void f(int i) {
+ ArgumentError.checkNotNull(i);
+}
+void g(bool b, int? i) {
+ if (b) f(i!);
+}
+main() {
+ g(false, null);
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
Future<void> test_as_allows_null() async {
var content = '''
int f(Object o) => (o as int)?.gcd(1);
@@ -269,6 +295,36 @@
await _checkSingleFileChanges(content, expected);
}
+ Future<void> test_assignment_to_promoted_var_can_undo_promotion() async {
+ var content = '''
+abstract class C {
+ void test() {
+ var x = f();
+ while (x != null) {
+ x = f();
+ }
+ }
+ int/*?*/ f();
+}
+''';
+ var expected = '''
+abstract class C {
+ void test() {
+ var x = f();
+ while (x != null) {
+ x = f();
+ }
+ }
+ int? f();
+}
+''';
+ // Prior to the fix for https://github.com/dart-lang/sdk/issues/41411,
+ // migration would consider the LHS of `x = f()` to have context type
+ // non-nullable `int`, so it would add a null check to the value returned
+ // from `f`.
+ await _checkSingleFileChanges(content, expected);
+ }
+
Future<void>
test_back_propagation_stops_at_implicitly_typed_variables() async {
var content = '''
@@ -4671,6 +4727,35 @@
await _checkSingleFileChanges(content, expected);
}
+ Future<void> test_quiver_checkNotNull_implies_non_null_intent() async {
+ addQuiverPackage();
+ var content = '''
+import 'package:quiver/check.dart';
+void f(int i) {
+ checkNotNull(i);
+}
+void g(bool b, int i) {
+ if (b) f(i);
+}
+main() {
+ g(false, null);
+}
+''';
+ var expected = '''
+import 'package:quiver/check.dart';
+void f(int i) {
+ checkNotNull(i);
+}
+void g(bool b, int? i) {
+ if (b) f(i!);
+}
+main() {
+ g(false, null);
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
Future<void> test_redirecting_constructor_factory() async {
var content = '''
class C {
@@ -4978,6 +5063,118 @@
await _checkSingleFileChanges(content, expected);
}
+ Future<void> test_testVariable_assignedNullableValue() async {
+ addTestCorePackage();
+ var content = '''
+import 'package:test/test.dart';
+void main() {
+ int i;
+ setUp(() {
+ i = null;
+ });
+ test('a', () {
+ i.isEven;
+ });
+}
+''';
+ var expected = '''
+import 'package:test/test.dart';
+void main() {
+ int? i;
+ setUp(() {
+ i = null;
+ });
+ test('a', () {
+ i!.isEven;
+ });
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
+ Future<void> test_testVariable_downstreamAllNonNull() async {
+ addTestCorePackage();
+ var content = '''
+import 'package:test/test.dart';
+void main() {
+ int i;
+ setUp(() {
+ i = 1;
+ });
+ test('a', () {
+ i.isEven;
+ });
+}
+''';
+ var expected = '''
+import 'package:test/test.dart';
+void main() {
+ late int i;
+ setUp(() {
+ i = 1;
+ });
+ test('a', () {
+ i.isEven;
+ });
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
+ Future<void> test_testVariable_hasInitializer() async {
+ addTestCorePackage();
+ var content = '''
+import 'package:test/test.dart';
+void main() {
+ int i = 1;
+ setUp(() {
+ i = 1;
+ });
+}
+''';
+ var expected = '''
+import 'package:test/test.dart';
+void main() {
+ int i = 1;
+ setUp(() {
+ i = 1;
+ });
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
+ Future<void> test_testVariable_usedAsNullable() async {
+ addTestCorePackage();
+ var content = '''
+import 'package:test/test.dart';
+void main() {
+ int i;
+ setUp(() {
+ i = 1;
+ });
+ test('a', () {
+ f(i);
+ });
+ f(int /*?*/ i) {}
+}
+''';
+ var expected = '''
+import 'package:test/test.dart';
+void main() {
+ late int i;
+ setUp(() {
+ i = 1;
+ });
+ test('a', () {
+ f(i);
+ });
+ f(int? i) {}
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
Future<void> test_topLevelFunction_parameterType_implicit_dynamic() async {
var content = '''
Object f(x) => x;
diff --git a/pkg/nnbd_migration/test/edge_builder_test.dart b/pkg/nnbd_migration/test/edge_builder_test.dart
index 8babb8a..145e37b 100644
--- a/pkg/nnbd_migration/test/edge_builder_test.dart
+++ b/pkg/nnbd_migration/test/edge_builder_test.dart
@@ -578,6 +578,42 @@
hard: false);
}
+ Future<void> test_ArgumentError_checkNotNull_not_postDominating() async {
+ await analyze('''
+void f(bool b, int i, int j) {
+ ArgumentError.checkNotNull(j);
+ if (b) return;
+ ArgumentError.checkNotNull(i);
+}
+''');
+
+ // Asserts after ifs don't demonstrate non-null intent.
+ assertNoEdge(decoratedTypeAnnotation('int i').node, never);
+ // But asserts before ifs do
+ assertEdge(decoratedTypeAnnotation('int j').node, never, hard: true);
+ }
+
+ Future<void> test_ArgumentError_checkNotNull_postDominating() async {
+ await analyze('''
+void f(int i) {
+ ArgumentError.checkNotNull(i);
+}
+''');
+
+ assertEdge(decoratedTypeAnnotation('int i').node, never, hard: true);
+ }
+
+ Future<void> test_ArgumentError_checkNotNull_prefixed() async {
+ await analyze('''
+import 'dart:core' as core;
+void f(core.int i) {
+ core.ArgumentError.checkNotNull(i);
+}
+''');
+
+ assertEdge(decoratedTypeAnnotation('int i').node, never, hard: true);
+ }
+
Future<void> test_as_dynamic() async {
await analyze('''
void f(Object o) {
@@ -6472,6 +6508,47 @@
assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
}
+ Future<void> test_quiver_checkNotNull_not_postDominating() async {
+ addQuiverPackage();
+ await analyze('''
+import 'package:quiver/check.dart';
+void f(bool b, int i, int j) {
+ checkNotNull(j);
+ if (b) return;
+ checkNotNull(i);
+}
+''');
+
+ // Asserts after ifs don't demonstrate non-null intent.
+ assertNoEdge(decoratedTypeAnnotation('int i').node, never);
+ // But asserts before ifs do
+ assertEdge(decoratedTypeAnnotation('int j').node, never, hard: true);
+ }
+
+ Future<void> test_quiver_checkNotNull_postDominating() async {
+ addQuiverPackage();
+ await analyze('''
+import 'package:quiver/check.dart';
+void f(int i) {
+ checkNotNull(i);
+}
+''');
+
+ assertEdge(decoratedTypeAnnotation('int i').node, never, hard: true);
+ }
+
+ Future<void> test_quiver_checkNotNull_prefixed() async {
+ addQuiverPackage();
+ await analyze('''
+import 'package:quiver/check.dart' as quiver;
+void f(int i) {
+ quiver.checkNotNull(i);
+}
+''');
+
+ assertEdge(decoratedTypeAnnotation('int i').node, never, hard: true);
+ }
+
Future<void> test_redirecting_constructor_factory() async {
await analyze('''
class C {
@@ -6921,6 +6998,140 @@
assertEdge(string1.node, string2.node, hard: true);
}
+ Future<void> test_setupAssignment_assignment_inDistantSetUp() async {
+ addTestCorePackage();
+ await analyze('''
+import 'package:test/test.dart';
+void main() {
+ int i;
+ // There could be tests here in which [i] is not certain to have been
+ // assigned.
+
+ group('g2', () {
+ setUp(() {
+ i = 1;
+ });
+ });
+}
+''');
+
+ assertNoEdge(graph.never, decoratedTypeAnnotation('int').node);
+ }
+
+ Future<void> test_setupAssignment_assignment_inSetUp() async {
+ addTestCorePackage();
+ await analyze('''
+import 'package:test/test.dart';
+void main() {
+ int i;
+ int j = 1;
+ setUp(() {
+ i = j;
+ });
+}
+''');
+
+ assertNullCheck(
+ checkExpression('j;'),
+ assertEdge(decoratedTypeAnnotation('int j').node,
+ decoratedTypeAnnotation('int i').node,
+ hard: false, isSetupAssignment: true));
+ }
+
+ Future<void> test_setupAssignment_assignment_inUnrelatedSetUp() async {
+ addTestCorePackage();
+ await analyze('''
+import 'package:test/test.dart';
+void main() {
+ group('g1', () {
+ int/*1*/ i;
+ });
+
+ group('g2', () {
+ int/*2*/ i;
+ int j = 1;
+ setUp(() {
+ i = j;
+ });
+ });
+}
+''');
+
+ assertNoEdge(graph.never, decoratedTypeAnnotation('int/*1*/').node);
+ assertNullCheck(
+ checkExpression('j;'),
+ assertEdge(decoratedTypeAnnotation('int j').node,
+ decoratedTypeAnnotation('int/*2*/').node,
+ hard: false, isSetupAssignment: true));
+ }
+
+ Future<void> test_setupAssignment_assignment_inWrongSetUp() async {
+ addTestCorePackage();
+ await analyze('''
+import 'package:test/test.dart' as t;
+void main() {
+ int i;
+ setUp(() {
+ i = 1;
+ });
+}
+void setUp(dynamic callback()) {}
+''');
+
+ assertNoEdge(graph.never, decoratedTypeAnnotation('int').node);
+ }
+
+ Future<void> test_setupAssignment_assignment_outsideSetUp() async {
+ addTestCorePackage();
+ await analyze('''
+import 'package:test/test.dart';
+void main() {
+ int i;
+ i = 1;
+}
+''');
+
+ assertNoEdge(graph.never, decoratedTypeAnnotation('int').node);
+ }
+
+ Future<void> test_setupAssignment_assignment_toField() async {
+ addTestCorePackage();
+ await analyze('''
+import 'package:test/test.dart';
+void main() {
+ setUp(() {
+ C c = C();
+ c.i = 1;
+ });
+}
+class C {
+ int i;
+}
+''');
+
+ assertNoEdge(graph.never, decoratedTypeAnnotation('int').node);
+ }
+
+ Future<void> test_setupAssignment_nullAwareAssignment_inSetUp() async {
+ addTestCorePackage();
+ await analyze('''
+import 'package:test/test.dart';
+void main() {
+ int i;
+ int j = 1;
+ setUp(() {
+ i ??= j;
+ });
+}
+''');
+
+ var iNullable = decoratedTypeAnnotation('int i').node;
+ assertNullCheck(
+ checkExpression('j;'),
+ assertEdge(decoratedTypeAnnotation('int j').node, iNullable,
+ hard: false, guards: [iNullable], isSetupAssignment: true));
+ }
+
Future<void> test_simpleIdentifier_bangHint() async {
await analyze('''
int f1(int i1) => i1;
diff --git a/pkg/nnbd_migration/test/fix_builder_test.dart b/pkg/nnbd_migration/test/fix_builder_test.dart
index 4a03e5b..e8b600b 100644
--- a/pkg/nnbd_migration/test/fix_builder_test.dart
+++ b/pkg/nnbd_migration/test/fix_builder_test.dart
@@ -342,6 +342,16 @@
visitSubexpression(findNode.assignment('??='), '_C?');
}
+ Future<void> test_assignmentExpression_null_aware_simple_promoted() async {
+ await analyze('''
+_f(bool/*?*/ x, bool/*?*/ y) => x != null && (x ??= y) != null;
+''');
+ // On the RHS of the `&&`, `x` is promoted to non-nullable, but it is still
+ // considered to be a nullable assignment target, so no null check is
+ // generated for `y`.
+ visitSubexpression(findNode.binary('&&'), 'bool');
+ }
+
Future<void>
test_assignmentExpression_simple_nonNullable_to_nonNullable() async {
await analyze('''
@@ -374,7 +384,6 @@
visitSubexpression(findNode.assignment('= '), 'int?');
}
- @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/39641')
Future<void> test_assignmentExpression_simple_promoted() async {
await analyze('''
_f(bool/*?*/ x, bool/*?*/ y) => x != null && (x = y) != null;
diff --git a/pkg/nnbd_migration/test/front_end/analysis_abstract.dart b/pkg/nnbd_migration/test/front_end/analysis_abstract.dart
index f4833cc..d371a67 100644
--- a/pkg/nnbd_migration/test/front_end/analysis_abstract.dart
+++ b/pkg/nnbd_migration/test/front_end/analysis_abstract.dart
@@ -20,10 +20,12 @@
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:test/test.dart';
+import '../abstract_context.dart';
import 'mocks.dart';
/// An abstract base for all 'analysis' domain tests.
-class AbstractAnalysisTest with ResourceProviderMixin {
+class AbstractAnalysisTest extends AbstractContextTest
+ with ResourceProviderMixin {
bool generateSummaryFiles = false;
MockServerChannel serverChannel;
TestPluginManager pluginManager;
@@ -181,10 +183,11 @@
}
void setUp() {
+ super.setUp();
serverChannel = MockServerChannel();
- projectPath = convertPath('/project');
- testFolder = convertPath('/project/bin');
- testFile = convertPath('/project/bin/test.dart');
+ projectPath = convertPath(AbstractContextTest.testsPath);
+ testFolder = convertPath('${AbstractContextTest.testsPath}/bin');
+ testFile = convertPath('${AbstractContextTest.testsPath}/bin/test.dart');
pluginManager = TestPluginManager();
server = createAnalysisServer();
server.pluginManager = pluginManager;
diff --git a/pkg/nnbd_migration/test/front_end/info_builder_test.dart b/pkg/nnbd_migration/test/front_end/info_builder_test.dart
index cba5d32..b9e06f2 100644
--- a/pkg/nnbd_migration/test/front_end/info_builder_test.dart
+++ b/pkg/nnbd_migration/test/front_end/info_builder_test.dart
@@ -323,6 +323,47 @@
replacement: ''));
}
+ Future<void> test_addLate_dueToTestSetup() async {
+ addTestCorePackage();
+ var content = '''
+import 'package:test/test.dart';
+void main() {
+ int i;
+ setUp(() {
+ i = 1;
+ });
+ test('a', () {
+ f(i);
+ });
+ f(int /*?*/ i) {}
+}
+''';
+ var migratedContent = '''
+import 'package:test/test.dart';
+void main() {
+ late int i;
+ setUp(() {
+ i = 1;
+ });
+ test('a', () {
+ f(i);
+ });
+ f(int /*?*/ i) {}
+}
+''';
+ var unit = await buildInfoForSingleTestFile(content,
+ migratedContent: migratedContent);
+ var regions = unit.fixRegions;
+ expect(regions, hasLength(3));
+ var region = regions[0];
+ assertRegion(
+ region: region,
+ offset: 49,
+ length: 4,
+ explanation: 'Added a late keyword, due to assignment in `setUp`',
+ kind: NullabilityFixKind.addLateDueToTestSetup);
+ }
+
Future<void> test_conditionFalseInStrongMode_expression() async {
var unit = await buildInfoForSingleTestFile(
'int f(String s) => s == null ? 0 : s.length;',
diff --git a/pkg/nnbd_migration/test/front_end/region_renderer_test.dart b/pkg/nnbd_migration/test/front_end/region_renderer_test.dart
index db9bcfe..934614a 100644
--- a/pkg/nnbd_migration/test/front_end/region_renderer_test.dart
+++ b/pkg/nnbd_migration/test/front_end/region_renderer_test.dart
@@ -9,6 +9,7 @@
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
+import '../abstract_context.dart';
import 'nnbd_migration_test_base.dart';
void main() {
@@ -43,7 +44,8 @@
await buildInfoForSingleTestFile('int a = null;',
migratedContent: 'int? a = null;');
var response = renderRegion(3);
- expect(response.path, equals(convertPath('/project/bin/test.dart')));
+ expect(response.path,
+ equals(convertPath('${AbstractContextTest.testsPath}/bin/test.dart')));
expect(response.line, equals(1));
}
@@ -58,7 +60,8 @@
await buildInfoForSingleTestFile('f(int a) => a.isEven;',
migratedContent: 'f(int a) => a.isEven;');
var response = renderRegion(5);
- expect(response.path, equals(convertPath('/project/bin/test.dart')));
+ expect(response.path,
+ equals(convertPath('${AbstractContextTest.testsPath}/bin/test.dart')));
expect(response.line, equals(1));
}
}
diff --git a/pkg/nnbd_migration/test/migration_cli_test.dart b/pkg/nnbd_migration/test/migration_cli_test.dart
index a841013..b375b60 100644
--- a/pkg/nnbd_migration/test/migration_cli_test.dart
+++ b/pkg/nnbd_migration/test/migration_cli_test.dart
@@ -5,6 +5,7 @@
import 'dart:async';
import 'dart:io';
+import 'package:analysis_server/src/edit/fix/non_nullable_fix.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/src/test_utilities/mock_sdk.dart' as mock_sdk;
@@ -18,56 +19,62 @@
main() {
defineReflectiveSuite(() {
- defineReflectiveTests(_MigrationCliTest);
+ defineReflectiveTests(_MigrationCliTestPosix);
+ defineReflectiveTests(_MigrationCliTestWindows);
});
}
class _MigrationCli extends MigrationCli {
- Completer<void> _previewServerStartedCompleter;
+ Future<void> Function() _runWhilePreviewServerActive;
- Completer<void> _signalInterruptCompleter;
-
- _MigrationCli(_MigrationCliTest test)
+ _MigrationCli(_MigrationCliTestBase test)
: super(
binaryName: 'nnbd_migration',
loggerFactory: (isVerbose) => test.logger = _TestLogger(isVerbose),
- defaultSdkPathOverride: mock_sdk.sdkRoot,
+ defaultSdkPathOverride:
+ test.resourceProvider.convertPath(mock_sdk.sdkRoot),
resourceProvider: test.resourceProvider);
@override
- Future<void> blockUntilSignalInterrupt() {
- _previewServerStartedCompleter.complete();
- _signalInterruptCompleter = Completer<void>();
- return _signalInterruptCompleter.future;
+ Future<void> blockUntilSignalInterrupt() async {
+ if (_runWhilePreviewServerActive == null) {
+ fail('Preview server not expected to have been started');
+ }
+ await _runWhilePreviewServerActive.call();
+ _runWhilePreviewServerActive = null;
}
Future<void> runWithPreviewServer(
List<String> args, Future<void> callback()) async {
- _previewServerStartedCompleter = Completer<void>();
- var done = run(args);
- await _previewServerStartedCompleter.future;
- await callback();
- _signalInterruptCompleter.complete();
- return done;
+ _runWhilePreviewServerActive = callback;
+ await run(args);
+ if (_runWhilePreviewServerActive != null) {
+ fail('Preview server never started');
+ }
}
}
-@reflectiveTest
-class _MigrationCliTest {
+abstract class _MigrationCliTestBase {
+ void set logger(_TestLogger logger);
+
+ MemoryResourceProvider get resourceProvider;
+}
+
+mixin _MigrationCliTestMethods on _MigrationCliTestBase {
+ @override
/*late*/ _TestLogger logger;
final hasVerboseHelpMessage = contains('for verbose help output');
final hasUsageText = contains('Usage: nnbd_migration');
- final resourceProvider = MemoryResourceProvider();
-
- String assertErrorExit(MigrationCli cli) {
+ String assertErrorExit(MigrationCli cli, {bool withUsage = true}) {
expect(cli.exitCode, isNotNull);
expect(cli.exitCode, isNot(0));
var stderrText = logger.stderrBuffer.toString();
- expect(stderrText, hasUsageText);
- expect(stderrText, hasVerboseHelpMessage);
+ expect(stderrText, withUsage ? hasUsageText : isNot(hasUsageText));
+ expect(stderrText,
+ withUsage ? hasVerboseHelpMessage : isNot(hasVerboseHelpMessage));
return stderrText;
}
@@ -87,6 +94,11 @@
return options;
}
+ Future assertPreviewServerResponsive(String url) async {
+ var response = await http.get(url);
+ expect(response.statusCode, 200);
+ }
+
void assertProjectContents(String projectDir, Map<String, String> expected) {
for (var entry in expected.entries) {
var relativePathPosix = entry.key;
@@ -110,26 +122,66 @@
return resourceProvider.convertPath(projectPathPosix);
}
- Map<String, String> simpleProject({bool migrated: false}) {
- // TODO(paulberry): pubspec needs to be updated when migrating.
+ Future<void> runWithPreviewServer(_MigrationCli cli, List<String> args,
+ Future<void> Function(String) callback) async {
+ String url;
+ await cli.runWithPreviewServer(args, () async {
+ // Server should be running now
+ url = RegExp('http://.*', multiLine: true)
+ .stringMatch(logger.stdoutBuffer.toString());
+ await callback(url);
+ });
+ // Server should be stopped now
+ expect(http.get(url), throwsA(anything));
+ }
+
+ Map<String, String> simpleProject({bool migrated: false, String sourceText}) {
return {
'pubspec.yaml': '''
name: test
environment:
-sdk: '>=2.6.0 <3.0.0'
+ sdk: '${migrated ? '>=2.9.0 <2.10.0' : '>=2.6.0 <3.0.0'}'
''',
- 'lib/test.dart': '''
+ 'lib/test.dart': sourceText ??
+ '''
int${migrated ? '?' : ''} f() => null;
'''
};
}
+ void tearDown() {
+ NonNullableFix.shutdownAllServers();
+ }
+
test_default_logger() {
// When running normally, we don't override the logger; make sure it has a
// non-null default so that there won't be a crash.
expect(MigrationCli(binaryName: 'nnbd_migration').logger, isNotNull);
}
+ test_detect_old_sdk() async {
+ var cli = _createCli();
+ // Alter the mock SDK, changing the signature of Object.operator== to match
+ // the signature that was present prior to NNBD. (This is what the
+ // migration tool uses to detect an old SDK).
+ var coreLib = resourceProvider.getFile(
+ resourceProvider.convertPath('${mock_sdk.sdkRoot}/lib/core/core.dart'));
+ var oldCoreLibText = coreLib.readAsStringSync();
+ var newCoreLibText = oldCoreLibText.replaceAll(
+ 'external bool operator ==(Object other)',
+ 'external bool operator ==(dynamic other)');
+ expect(newCoreLibText, isNot(oldCoreLibText));
+ coreLib.writeAsStringSync(newCoreLibText);
+ var projectDir = await createProjectDir(simpleProject());
+ await cli.run([projectDir]);
+ assertErrorExit(cli, withUsage: false);
+ var output = logger.stdoutBuffer.toString();
+ expect(
+ output,
+ contains(
+ 'Bad state: Analysis seems to have an SDK without NNBD enabled'));
+ }
+
test_flag_apply_changes_default() {
expect(assertParseArgsSuccess([]).applyChanges, isFalse);
}
@@ -163,6 +215,18 @@
expect(helpText, isNot(hasVerboseHelpMessage));
}
+ test_flag_ignore_errors_default() {
+ expect(assertParseArgsSuccess([]).ignoreErrors, isFalse);
+ }
+
+ test_flag_ignore_errors_disable() async {
+ await assertParseArgsFailure(['--no-ignore-errors']);
+ }
+
+ test_flag_ignore_errors_enable() {
+ expect(assertParseArgsSuccess(['--ignore-errors']).ignoreErrors, isTrue);
+ }
+
test_flag_web_preview_default() {
expect(assertParseArgsSuccess([]).webPreview, isTrue);
}
@@ -182,14 +246,55 @@
await cli.run(['--no-web-preview', '--apply-changes', projectDir]);
// Check that a summary was printed
expect(logger.stdoutBuffer.toString(), contains('Applying changes'));
- // And that it refers to test.dart
+ // And that it refers to test.dart and pubspec.yaml
expect(logger.stdoutBuffer.toString(), contains('test.dart'));
+ expect(logger.stdoutBuffer.toString(), contains('pubspec.yaml'));
// And that it does not tell the user they can rerun with `--apply-changes`
expect(logger.stdoutBuffer.toString(), isNot(contains('--apply-changes')));
// Changes should have been made
assertProjectContents(projectDir, simpleProject(migrated: true));
}
+ test_lifecycle_ignore_errors_disable() async {
+ var projectContents = simpleProject(sourceText: '''
+int f() => null
+''');
+ var projectDir = await createProjectDir(projectContents);
+ var cli = _createCli();
+ await cli.run([projectDir]);
+ assertErrorExit(cli, withUsage: false);
+ var output = logger.stdoutBuffer.toString();
+ expect(output, contains('1 analysis issue found'));
+ var sep = resourceProvider.pathContext.separator;
+ expect(
+ output,
+ contains("error • Expected to find ';' at lib${sep}test.dart:1:12 • "
+ "(expected_token)"));
+ expect(
+ output,
+ contains(
+ 'analysis errors will result in erroneous migration suggestions'));
+ expect(output, contains('Please fix the analysis issues'));
+ }
+
+ test_lifecycle_ignore_errors_enable() async {
+ var projectContents = simpleProject(sourceText: '''
+int? f() => null
+''');
+ var projectDir = await createProjectDir(projectContents);
+ var cli = _createCli();
+ await runWithPreviewServer(cli, ['--ignore-errors', projectDir],
+ (url) async {
+ var output = logger.stdoutBuffer.toString();
+ expect(output, isNot(contains('No analysis issues found')));
+ expect(
+ output,
+ contains('Continuing with migration suggestions due to the use of '
+ '--ignore-errors.'));
+ await assertPreviewServerResponsive(url);
+ });
+ }
+
test_lifecycle_no_preview() async {
var projectContents = simpleProject();
var projectDir = await createProjectDir(projectContents);
@@ -197,8 +302,9 @@
await cli.run(['--no-web-preview', projectDir]);
// Check that a summary was printed
expect(logger.stdoutBuffer.toString(), contains('Summary'));
- // And that it refers to test.dart
+ // And that it refers to test.dart and pubspec.yaml
expect(logger.stdoutBuffer.toString(), contains('test.dart'));
+ expect(logger.stdoutBuffer.toString(), contains('pubspec.yaml'));
// And that it tells the user they can rerun with `--apply-changes`
expect(logger.stdoutBuffer.toString(), contains('--apply-changes'));
// No changes should have been made
@@ -209,20 +315,36 @@
var projectContents = simpleProject();
var projectDir = await createProjectDir(projectContents);
var cli = _createCli();
- String url;
- await cli.runWithPreviewServer([projectDir], () async {
- // Server should be running now
- url = RegExp('http://.*', multiLine: true)
- .stringMatch(logger.stdoutBuffer.toString());
- var response = await http.get(url);
- expect(response.statusCode, 200);
+ await runWithPreviewServer(cli, [projectDir], (url) async {
+ expect(
+ logger.stdoutBuffer.toString(), contains('No analysis issues found'));
+ await assertPreviewServerResponsive(url);
});
- // Server should be stopped now
- expect(http.get(url), throwsA(anything));
- // And no changes should have been made.
+ // No changes should have been made.
assertProjectContents(projectDir, projectContents);
}
+ test_lifecycle_uri_error() async {
+ var projectContents = simpleProject(sourceText: '''
+import 'package:does_not/exist.dart';
+int f() => null;
+''');
+ var projectDir = await createProjectDir(projectContents);
+ var cli = _createCli();
+ await cli.run([projectDir]);
+ assertErrorExit(cli, withUsage: false);
+ var output = logger.stdoutBuffer.toString();
+ expect(output, contains('1 analysis issue found'));
+ expect(output, contains('uri_does_not_exist'));
+ expect(
+ output,
+ contains(
+ 'analysis errors will result in erroneous migration suggestions'));
+ expect(output,
+ contains('Unresolved URIs found. Did you forget to run "pub get"?'));
+ expect(output, contains('Please fix the analysis issues'));
+ }
+
test_migrate_path_none() {
expect(assertParseArgsSuccess([]).directory, Directory.current.path);
}
@@ -297,6 +419,39 @@
}
}
+@reflectiveTest
+class _MigrationCliTestPosix extends _MigrationCliTestBase
+ with _MigrationCliTestMethods {
+ @override
+ final resourceProvider;
+
+ _MigrationCliTestPosix()
+ : resourceProvider = MemoryResourceProvider(
+ context: path.style == path.Style.posix ? null : path.posix);
+}
+
+@reflectiveTest
+class _MigrationCliTestWindows extends _MigrationCliTestBase
+ with _MigrationCliTestMethods {
+ @override
+ final resourceProvider;
+
+ _MigrationCliTestWindows()
+ : resourceProvider = MemoryResourceProvider(
+ context: path.style == path.Style.windows
+ ? null
+ : path.Context(style: path.Style.windows, current: 'C:\\'));
+
+ @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/40381')
+ @override
+ test_lifecycle_ignore_errors_enable() =>
+ super.test_lifecycle_ignore_errors_enable();
+
+ @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/40381')
+ @override
+ test_lifecycle_preview() => super.test_lifecycle_preview();
+}
+
/// TODO(paulberry): move into cli_util
class _TestLogger implements Logger {
final stderrBuffer = StringBuffer();
diff --git a/pkg/nnbd_migration/test/migration_visitor_test_base.dart b/pkg/nnbd_migration/test/migration_visitor_test_base.dart
index a789b23..c91a11c 100644
--- a/pkg/nnbd_migration/test/migration_visitor_test_base.dart
+++ b/pkg/nnbd_migration/test/migration_visitor_test_base.dart
@@ -193,6 +193,7 @@
return {for (var edge in getEdges(anyNode, graph.never)) edge.sourceNode};
}
+ /// Asserts that a dummy edge exists from [source] to always.
NullabilityEdge assertDummyEdge(Object source) =>
assertEdge(source, graph.always, hard: false, checkable: false);
@@ -201,10 +202,11 @@
///
/// [source] and [destination] are converted to [NodeMatcher] objects if they
/// aren't already. In practice this means that the caller can pass in either
- // /// a [NodeMatcher] or a [NullabilityNode].
+ /// a [NodeMatcher] or a [NullabilityNode].
NullabilityEdge assertEdge(Object source, Object destination,
{@required bool hard,
bool checkable = true,
+ bool isSetupAssignment = false,
Object guards = isEmpty,
Object codeReference}) {
var edges = getEdges(source, destination);
@@ -216,6 +218,7 @@
var edge = edges[0];
expect(edge.isHard, hard);
expect(edge.isCheckable, checkable);
+ expect(edge.isSetupAssignment, isSetupAssignment);
expect(edge.guards, guards);
if (codeReference != null) {
expect(edge.codeReference, codeReference);
diff --git a/pkg/nnbd_migration/tool/trial_migration.dart b/pkg/nnbd_migration/tool/trial_migration.dart
index 8731cef..21d4337 100644
--- a/pkg/nnbd_migration/tool/trial_migration.dart
+++ b/pkg/nnbd_migration/tool/trial_migration.dart
@@ -101,9 +101,13 @@
'seconds');
print('${listener.numTypesMadeNullable} types made nullable');
print('${listener.numNullChecksAdded} null checks added');
+ print('${listener.numVariablesMarkedLate} variables marked late');
+ print('${listener.numInsertedCasts} casts inserted');
+ print('${listener.numInsertedParenthesis} parenthesis groupings inserted');
print('${listener.numMetaImportsAdded} meta imports added');
print('${listener.numRequiredAnnotationsAdded} required annotations added');
print('${listener.numDeadCodeSegmentsFound} dead code segments found');
+ print('and ${listener.numOtherEdits} other edits not categorized');
print('${listener.numExceptions} exceptions in '
'${listener.groupedExceptions.length} categories');
@@ -125,25 +129,6 @@
}
}
-class ExceptionCategory {
- final String topOfStack;
- final List<MapEntry<String, int>> exceptionCountPerPackage;
-
- ExceptionCategory(this.topOfStack, Map<String, int> exceptions)
- : this.exceptionCountPerPackage = exceptions.entries.toList()
- ..sort((e1, e2) => e2.value.compareTo(e1.value));
-
- int get count => exceptionCountPerPackage.length;
-
- List<String> get packageNames =>
- [for (var entry in exceptionCountPerPackage) entry.key];
-
- Iterable<String> get packageNamesAndCounts =>
- exceptionCountPerPackage.map((entry) => '${entry.key} x${entry.value}');
-
- String toString() => '$topOfStack (${packageNamesAndCounts.join(', ')})';
-}
-
ArgResults parseArguments(List<String> args) {
ArgParser argParser = ArgParser();
ArgResults parsedArgs;
@@ -241,6 +226,25 @@
'SDK at ${sdk.sdkPath} not compiled with --nnbd, use --sdk option');
}
+class ExceptionCategory {
+ final String topOfStack;
+ final List<MapEntry<String, int>> exceptionCountPerPackage;
+
+ ExceptionCategory(this.topOfStack, Map<String, int> exceptions)
+ : this.exceptionCountPerPackage = exceptions.entries.toList()
+ ..sort((e1, e2) => e2.value.compareTo(e1.value));
+
+ int get count => exceptionCountPerPackage.length;
+
+ List<String> get packageNames =>
+ [for (var entry in exceptionCountPerPackage) entry.key];
+
+ Iterable<String> get packageNamesAndCounts =>
+ exceptionCountPerPackage.map((entry) => '${entry.key} x${entry.value}');
+
+ String toString() => '$topOfStack (${packageNamesAndCounts.join(', ')})';
+}
+
class _Listener implements NullabilityMigrationListener {
/// Set this to `true` to cause just the exception nodes to be printed when
/// `_Listener.categoryOfInterest` is non-null. Set this to `false` to cause
@@ -258,6 +262,12 @@
int numTypesMadeNullable = 0;
+ int numVariablesMarkedLate = 0;
+
+ int numInsertedCasts = 0;
+
+ int numInsertedParenthesis = 0;
+
int numNullChecksAdded = 0;
int numMetaImportsAdded = 0;
@@ -266,31 +276,50 @@
int numDeadCodeSegmentsFound = 0;
+ int numOtherEdits = 0;
+
String currentPackage;
_Listener(this.categoryOfInterest, {this.printExceptionNodeOnly = false});
@override
void addEdit(Source source, SourceEdit edit) {
+ if (edit.replacement == '') {
+ return;
+ }
+
+ if (edit.replacement.contains('!')) {
+ ++numNullChecksAdded;
+ }
+
+ if (edit.replacement.contains('(')) {
+ ++numInsertedParenthesis;
+ }
+
if (edit.replacement == '?' && edit.length == 0) {
++numTypesMadeNullable;
- } else if (edit.replacement == '!' && edit.length == 0) {
- ++numNullChecksAdded;
} else if (edit.replacement == "import 'package:meta/meta.dart';\n" &&
edit.length == 0) {
++numMetaImportsAdded;
} else if (edit.replacement == 'required ' && edit.length == 0) {
++numRequiredAnnotationsAdded;
+ } else if (edit.replacement == 'late ' && edit.length == 0) {
+ ++numVariablesMarkedLate;
+ } else if (edit.replacement.startsWith(' as ') && edit.length == 0) {
+ ++numInsertedCasts;
} else if ((edit.replacement == '/* ' ||
edit.replacement == ' /*' ||
edit.replacement == '; /*') &&
edit.length == 0) {
++numDeadCodeSegmentsFound;
- } else if ((edit.replacement == '*/ ' || edit.replacement == ' */') &&
+ } else if ((edit.replacement == '*/ ' ||
+ edit.replacement == ' */' ||
+ edit.replacement == ')' ||
+ edit.replacement == '!' ||
+ edit.replacement == '(') &&
edit.length == 0) {
- // Already counted
} else {
- print('addEdit($source, $edit)');
+ numOtherEdits++;
}
}
diff --git a/pkg/test_runner/lib/src/browser.dart b/pkg/test_runner/lib/src/browser.dart
index 60d3a92..279de73 100644
--- a/pkg/test_runner/lib/src/browser.dart
+++ b/pkg/test_runner/lib/src/browser.dart
@@ -232,7 +232,7 @@
};
if ($isNnbd) {
- sdk.dart.strictSubtypeChecks($isNnbdStrong);
+ sdk.dart.nullSafety($isNnbdStrong);
}
dartMainRunner(function testMainWrapper() {
diff --git a/pkg/vm/lib/transformations/mixin_deduplication.dart b/pkg/vm/lib/transformations/mixin_deduplication.dart
index fcf8224..f9bf6b9 100644
--- a/pkg/vm/lib/transformations/mixin_deduplication.dart
+++ b/pkg/vm/lib/transformations/mixin_deduplication.dart
@@ -9,15 +9,17 @@
/// De-duplication of identical mixin applications.
void transformComponent(Component component) {
final deduplicateMixins = new DeduplicateMixinsTransformer();
- final interfaceTargetResolver = InterfaceTargetResolver(deduplicateMixins);
+ final referenceUpdater = ReferenceUpdater(deduplicateMixins);
// Deduplicate mixins and re-resolve super initializers.
// (this is a shallow transformation)
component.libraries.forEach(deduplicateMixins.visitLibrary);
- // Do a deep transformation to re-resolve all interface targets that point to
- // members of removed mixin application classes.
-
+ // Do a deep transformation to update references to the removed mixin
+ // application classes in the interface targets and types.
+ //
+ // Interface targets pointing to members of removed mixin application
+ // classes are re-resolved at the remaining mixin applications.
// This is necessary iff the component was assembled from individual modular
// kernel compilations:
//
@@ -30,7 +32,11 @@
// TODO(dartbug.com/39375): Remove this extra O(N) pass over the AST if the
// CFE decides to consistently let the interface target point to the mixin
// class (instead of mixin application).
- component.libraries.forEach(interfaceTargetResolver.visitLibrary);
+ //
+ // Types could also contain references to removed mixin applications due to
+ // LUB algorithm in CFE (calculating static type of a conditional expression)
+ // and type inference which can spread types and produce derived types.
+ component.libraries.forEach(referenceUpdater.visitLibrary);
}
class _DeduplicateMixinKey {
@@ -140,46 +146,55 @@
throw 'Unexpected node ${node.runtimeType}: $node';
}
-/// Rewrites interface targets to point to the deduplicated mixin application
-/// class.
-class InterfaceTargetResolver extends RecursiveVisitor<TreeNode> {
+/// Rewrites references to the deduplicated mixin application
+/// classes. Updates interface targets and types.
+class ReferenceUpdater extends RecursiveVisitor<void> {
final DeduplicateMixinsTransformer transformer;
+ final _visitedConstants = new Set<Constant>.identity();
- InterfaceTargetResolver(this.transformer);
+ ReferenceUpdater(this.transformer);
- defaultTreeNode(TreeNode node) {
- node.visitChildren(this);
- return node;
+ @override
+ visitLibrary(Library node) {
+ super.visitLibrary(node);
+ // Avoid accumulating too many constants in case of huge programs.
+ _visitedConstants.clear();
}
+ @override
visitPropertyGet(PropertyGet node) {
node.interfaceTarget = _resolveNewInterfaceTarget(node.interfaceTarget);
- return super.visitPropertyGet(node);
+ super.visitPropertyGet(node);
}
+ @override
visitPropertySet(PropertySet node) {
node.interfaceTarget = _resolveNewInterfaceTarget(node.interfaceTarget);
- return super.visitPropertySet(node);
+ super.visitPropertySet(node);
}
+ @override
visitMethodInvocation(MethodInvocation node) {
node.interfaceTarget = _resolveNewInterfaceTarget(node.interfaceTarget);
- return super.visitMethodInvocation(node);
+ super.visitMethodInvocation(node);
}
+ @override
visitSuperPropertyGet(SuperPropertyGet node) {
node.interfaceTarget = _resolveNewInterfaceTarget(node.interfaceTarget);
- return super.visitSuperPropertyGet(node);
+ super.visitSuperPropertyGet(node);
}
+ @override
visitSuperPropertySet(SuperPropertySet node) {
node.interfaceTarget = _resolveNewInterfaceTarget(node.interfaceTarget);
- return super.visitSuperPropertySet(node);
+ super.visitSuperPropertySet(node);
}
+ @override
visitSuperMethodInvocation(SuperMethodInvocation node) {
node.interfaceTarget = _resolveNewInterfaceTarget(node.interfaceTarget);
- return super.visitSuperMethodInvocation(node);
+ super.visitSuperMethodInvocation(node);
}
Member _resolveNewInterfaceTarget(Member m) {
@@ -205,6 +220,45 @@
throw 'Hit unexpected interface target which is not a Field/Procedure';
}
}
+
+ @override
+ visitInterfaceType(InterfaceType node) {
+ node.className = _updateClassReference(node.className);
+ super.visitInterfaceType(node);
+ }
+
+ Reference _updateClassReference(Reference classRef) {
+ final Class c = classRef.asClass;
+ if (c != null && c.isAnonymousMixin) {
+ final Class replacement = transformer._duplicatedMixins[c];
+ if (replacement != null) {
+ return replacement.reference;
+ }
+ }
+ return classRef;
+ }
+
+ @override
+ defaultConstantReference(Constant node) {
+ // By default, RecursiveVisitor stops at constants. We need to go deeper
+ // into constants in order to update types which are only referenced from
+ // constants. However, constants are DAGs and not trees, so visiting
+ // the same constant multiple times should be avoided to prevent
+ // exponential running time.
+ if (_visitedConstants.add(node)) {
+ node.accept(this);
+ }
+ }
+
+ @override
+ visitClassReference(Class node) {
+ // Safeguard against any possible leaked uses of anonymous mixin
+ // applications which are not updated.
+ if (node.isAnonymousMixin && transformer._duplicatedMixins[node] != null) {
+ throw 'Unexpected reference to removed mixin application $node';
+ }
+ super.visitClassReference(node);
+ }
}
/// Corrects forwarding constructors inserted by mixin resolution after
diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
index 568fa5f..eb40122 100644
--- a/runtime/bin/gen_snapshot.cc
+++ b/runtime/bin/gen_snapshot.cc
@@ -670,7 +670,7 @@
}
auto isolate_group_data = std::unique_ptr<IsolateGroupData>(
- new IsolateGroupData(nullptr, nullptr, nullptr, nullptr, false));
+ new IsolateGroupData(nullptr, nullptr, nullptr, false));
Dart_Isolate isolate;
char* error = NULL;
diff --git a/runtime/bin/isolate_data.cc b/runtime/bin/isolate_data.cc
index 3bf497c..1547975 100644
--- a/runtime/bin/isolate_data.cc
+++ b/runtime/bin/isolate_data.cc
@@ -10,21 +10,16 @@
namespace bin {
IsolateGroupData::IsolateGroupData(const char* url,
- const char* package_root,
const char* packages_file,
AppSnapshot* app_snapshot,
bool isolate_run_app_snapshot)
: script_url((url != NULL) ? strdup(url) : NULL),
- package_root(NULL),
app_snapshot_(app_snapshot),
resolved_packages_config_(NULL),
kernel_buffer_(NULL),
kernel_buffer_size_(0),
isolate_run_app_snapshot_(isolate_run_app_snapshot) {
- if (package_root != NULL) {
- ASSERT(packages_file == NULL);
- package_root = strdup(package_root);
- } else if (packages_file != NULL) {
+ if (packages_file != NULL) {
packages_file_ = strdup(packages_file);
}
}
@@ -32,8 +27,6 @@
IsolateGroupData::~IsolateGroupData() {
free(script_url);
script_url = NULL;
- free(package_root);
- package_root = NULL;
free(packages_file_);
packages_file_ = NULL;
free(resolved_packages_config_);
diff --git a/runtime/bin/isolate_data.h b/runtime/bin/isolate_data.h
index c4523a1..6dae87a 100644
--- a/runtime/bin/isolate_data.h
+++ b/runtime/bin/isolate_data.h
@@ -34,14 +34,12 @@
class IsolateGroupData {
public:
IsolateGroupData(const char* url,
- const char* package_root,
const char* packages_file,
AppSnapshot* app_snapshot,
bool isolate_run_app_snapshot);
~IsolateGroupData();
char* script_url;
- char* package_root;
const std::shared_ptr<uint8_t>& kernel_buffer() const {
return kernel_buffer_;
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index ac3baa5..06b9109 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -180,7 +180,7 @@
// Prepare builtin and other core libraries for use to resolve URIs.
// Set up various closures, e.g: printing, timers etc.
- // Set up 'package root' for URI resolution.
+ // Set up package configuration for URI resolution.
result = DartUtils::PrepareForScriptLoading(false, Options::trace_loading());
if (Dart_IsError(result)) return result;
@@ -417,7 +417,6 @@
// For now we only support the kernel isolate coming up from an
// application snapshot or from a .dill file.
static Dart_Isolate CreateAndSetupKernelIsolate(const char* script_uri,
- const char* package_root,
const char* packages_config,
Dart_IsolateFlags* flags,
char** error,
@@ -459,9 +458,8 @@
app_snapshot->SetBuffers(
&ignore_vm_snapshot_data, &ignore_vm_snapshot_instructions,
&isolate_snapshot_data, &isolate_snapshot_instructions);
- isolate_group_data =
- new IsolateGroupData(uri, package_root, packages_config, app_snapshot,
- isolate_run_app_snapshot);
+ isolate_group_data = new IsolateGroupData(
+ uri, packages_config, app_snapshot, isolate_run_app_snapshot);
isolate_data = new IsolateData(isolate_group_data);
isolate = Dart_CreateIsolateGroup(
DART_KERNEL_ISOLATE_NAME, DART_KERNEL_ISOLATE_NAME,
@@ -479,8 +477,8 @@
intptr_t kernel_service_buffer_size = 0;
dfe.LoadKernelService(&kernel_service_buffer, &kernel_service_buffer_size);
ASSERT(kernel_service_buffer != NULL);
- isolate_group_data = new IsolateGroupData(
- uri, package_root, packages_config, nullptr, isolate_run_app_snapshot);
+ isolate_group_data = new IsolateGroupData(uri, packages_config, nullptr,
+ isolate_run_app_snapshot);
isolate_group_data->SetKernelBufferUnowned(
const_cast<uint8_t*>(kernel_service_buffer),
kernel_service_buffer_size);
@@ -508,7 +506,6 @@
// For now we only support the service isolate coming up from sources
// which are compiled by the VM parser.
static Dart_Isolate CreateAndSetupServiceIsolate(const char* script_uri,
- const char* package_root,
const char* packages_config,
Dart_IsolateFlags* flags,
char** error,
@@ -516,8 +513,8 @@
#if !defined(PRODUCT)
ASSERT(script_uri != NULL);
Dart_Isolate isolate = NULL;
- auto isolate_group_data = new IsolateGroupData(
- script_uri, package_root, packages_config, nullptr, false);
+ auto isolate_group_data =
+ new IsolateGroupData(script_uri, packages_config, nullptr, false);
#if defined(DART_PRECOMPILED_RUNTIME)
// AOT: All isolates start from the app snapshot.
@@ -580,7 +577,6 @@
bool is_main_isolate,
const char* script_uri,
const char* name,
- const char* package_root,
const char* packages_config,
Dart_IsolateFlags* flags,
void* callback_data,
@@ -637,9 +633,8 @@
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)
- auto isolate_group_data =
- new IsolateGroupData(script_uri, package_root, packages_config,
- app_snapshot, isolate_run_app_snapshot);
+ auto isolate_group_data = new IsolateGroupData(
+ script_uri, packages_config, app_snapshot, isolate_run_app_snapshot);
if (kernel_buffer != NULL) {
if (parent_kernel_buffer) {
isolate_group_data->SetKernelBufferAlreadyOwned(
@@ -716,28 +711,22 @@
// The VM should never call the isolate helper with a NULL flags.
ASSERT(flags != NULL);
ASSERT(flags->version == DART_FLAGS_CURRENT_VERSION);
- if ((package_root != NULL) && (package_config != NULL)) {
- *error = strdup(
- "Invalid arguments - Cannot simultaneously specify "
- "package root and package map.");
- return NULL;
- }
-
+ ASSERT(package_root == nullptr);
int exit_code = 0;
#if !defined(EXCLUDE_CFE_AND_KERNEL_PLATFORM)
if (strcmp(script_uri, DART_KERNEL_ISOLATE_NAME) == 0) {
- return CreateAndSetupKernelIsolate(script_uri, package_root, package_config,
- flags, error, &exit_code);
+ return CreateAndSetupKernelIsolate(script_uri, package_config, flags, error,
+ &exit_code);
}
#endif // !defined(EXCLUDE_CFE_AND_KERNEL_PLATFORM)
if (strcmp(script_uri, DART_VM_SERVICE_ISOLATE_NAME) == 0) {
- return CreateAndSetupServiceIsolate(
- script_uri, package_root, package_config, flags, error, &exit_code);
+ return CreateAndSetupServiceIsolate(script_uri, package_config, flags,
+ error, &exit_code);
}
bool is_main_isolate = false;
return CreateIsolateGroupAndSetupHelper(is_main_isolate, script_uri, main,
- package_root, package_config, flags,
- callback_data, error, &exit_code);
+ package_config, flags, callback_data,
+ error, &exit_code);
}
static void OnIsolateShutdown(void* isolate_group_data, void* isolate_data) {
@@ -845,10 +834,15 @@
Dart_IsolateFlags flags;
Dart_IsolateFlagsInitialize(&flags);
+ if (Options::package_root() != nullptr) {
+ Syslog::PrintErr(
+ "Warning: The --package-root option is deprecated (was: %s)\n",
+ Options::package_root());
+ }
+
Dart_Isolate isolate = CreateIsolateGroupAndSetupHelper(
- is_main_isolate, script_name, "main", Options::package_root(),
- Options::packages_file(), &flags, NULL /* callback_data */, &error,
- &exit_code);
+ is_main_isolate, script_name, "main", Options::packages_file(), &flags,
+ NULL /* callback_data */, &error, &exit_code);
if (isolate == NULL) {
Syslog::PrintErr("%s\n", error);
diff --git a/runtime/bin/run_vm_tests.cc b/runtime/bin/run_vm_tests.cc
index 5e44275..c7b4df6 100644
--- a/runtime/bin/run_vm_tests.cc
+++ b/runtime/bin/run_vm_tests.cc
@@ -101,7 +101,6 @@
}
static Dart_Isolate CreateAndSetupServiceIsolate(const char* script_uri,
- const char* package_root,
const char* packages_config,
Dart_IsolateFlags* flags,
char** error) {
@@ -117,7 +116,7 @@
ASSERT(script_uri != nullptr);
Dart_Isolate isolate = nullptr;
auto isolate_group_data = new bin::IsolateGroupData(
- script_uri, package_root, packages_config, /*app_snapshot=*/nullptr,
+ script_uri, packages_config, /*app_snapshot=*/nullptr,
/*isolate_run_app_snapshot=*/false);
const uint8_t* kernel_buffer = nullptr;
@@ -169,9 +168,10 @@
void* data,
char** error) {
ASSERT(script_uri != nullptr);
+ ASSERT(package_root == nullptr);
if (strcmp(script_uri, DART_VM_SERVICE_ISOLATE_NAME) == 0) {
- return CreateAndSetupServiceIsolate(script_uri, package_root,
- packages_config, flags, error);
+ return CreateAndSetupServiceIsolate(script_uri, packages_config, flags,
+ error);
}
const bool is_kernel_isolate =
strcmp(script_uri, DART_KERNEL_ISOLATE_NAME) == 0;
@@ -200,9 +200,8 @@
app_snapshot->SetBuffers(
&ignore_vm_snapshot_data, &ignore_vm_snapshot_instructions,
&isolate_snapshot_data, &isolate_snapshot_instructions);
- isolate_group_data =
- new bin::IsolateGroupData(script_uri, package_root, packages_config,
- app_snapshot, app_snapshot != nullptr);
+ isolate_group_data = new bin::IsolateGroupData(
+ script_uri, packages_config, app_snapshot, app_snapshot != nullptr);
isolate = Dart_CreateIsolateGroup(
DART_KERNEL_ISOLATE_NAME, DART_KERNEL_ISOLATE_NAME,
isolate_snapshot_data, isolate_snapshot_instructions, flags,
@@ -229,8 +228,8 @@
bin::dfe.LoadKernelService(&kernel_service_buffer,
&kernel_service_buffer_size);
ASSERT(kernel_service_buffer != nullptr);
- isolate_group_data = new bin::IsolateGroupData(
- script_uri, package_root, packages_config, nullptr, false);
+ isolate_group_data =
+ new bin::IsolateGroupData(script_uri, packages_config, nullptr, false);
isolate_group_data->SetKernelBufferUnowned(
const_cast<uint8_t*>(kernel_service_buffer),
kernel_service_buffer_size);
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index b01cedc..c8fd5f8 100644
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -571,10 +571,7 @@
* eventually run. This is provided for advisory purposes only to
* improve debugging messages. The main function is not invoked by
* this function.
- * \param package_root The package root path for this isolate to resolve
- * package imports against. Only one of package_root and package_map
- * parameters is non-NULL. If neither parameter is passed the package
- * resolution of the parent isolate should be used.
+ * \param package_root Ignored.
* \param package_map The package map for this isolate to resolve package
* imports against. The array contains alternating keys and values,
* terminated by a NULL key. Only one of package_root and package_map
diff --git a/runtime/lib/isolate.cc b/runtime/lib/isolate.cc
index 4ef798d..059299d 100644
--- a/runtime/lib/isolate.cc
+++ b/runtime/lib/isolate.cc
@@ -390,7 +390,7 @@
return result;
}
-DEFINE_NATIVE_ENTRY(Isolate_spawnFunction, 0, 11) {
+DEFINE_NATIVE_ENTRY(Isolate_spawnFunction, 0, 10) {
GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0));
GET_NON_NULL_NATIVE_ARGUMENT(String, script_uri, arguments->NativeArgAt(1));
GET_NON_NULL_NATIVE_ARGUMENT(Instance, closure, arguments->NativeArgAt(2));
@@ -399,9 +399,8 @@
GET_NATIVE_ARGUMENT(Bool, fatalErrors, arguments->NativeArgAt(5));
GET_NATIVE_ARGUMENT(SendPort, onExit, arguments->NativeArgAt(6));
GET_NATIVE_ARGUMENT(SendPort, onError, arguments->NativeArgAt(7));
- GET_NATIVE_ARGUMENT(String, packageRoot, arguments->NativeArgAt(8));
- GET_NATIVE_ARGUMENT(String, packageConfig, arguments->NativeArgAt(9));
- GET_NATIVE_ARGUMENT(String, debugName, arguments->NativeArgAt(10));
+ GET_NATIVE_ARGUMENT(String, packageConfig, arguments->NativeArgAt(8));
+ GET_NATIVE_ARGUMENT(String, debugName, arguments->NativeArgAt(9));
if (closure.IsClosure()) {
Function& func = Function::Handle();
@@ -482,26 +481,19 @@
return result;
}
-DEFINE_NATIVE_ENTRY(Isolate_spawnUri, 0, 13) {
+DEFINE_NATIVE_ENTRY(Isolate_spawnUri, 0, 12) {
GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0));
GET_NON_NULL_NATIVE_ARGUMENT(String, uri, arguments->NativeArgAt(1));
-
GET_NON_NULL_NATIVE_ARGUMENT(Instance, args, arguments->NativeArgAt(2));
GET_NON_NULL_NATIVE_ARGUMENT(Instance, message, arguments->NativeArgAt(3));
-
GET_NON_NULL_NATIVE_ARGUMENT(Bool, paused, arguments->NativeArgAt(4));
GET_NATIVE_ARGUMENT(SendPort, onExit, arguments->NativeArgAt(5));
GET_NATIVE_ARGUMENT(SendPort, onError, arguments->NativeArgAt(6));
-
GET_NATIVE_ARGUMENT(Bool, fatalErrors, arguments->NativeArgAt(7));
GET_NATIVE_ARGUMENT(Bool, checked, arguments->NativeArgAt(8));
-
GET_NATIVE_ARGUMENT(Array, environment, arguments->NativeArgAt(9));
-
- GET_NATIVE_ARGUMENT(String, packageRoot, arguments->NativeArgAt(10));
- GET_NATIVE_ARGUMENT(String, packageConfig, arguments->NativeArgAt(11));
-
- GET_NATIVE_ARGUMENT(String, debugName, arguments->NativeArgAt(12));
+ GET_NATIVE_ARGUMENT(String, packageConfig, arguments->NativeArgAt(10));
+ GET_NATIVE_ARGUMENT(String, debugName, arguments->NativeArgAt(11));
if (Dart::vm_snapshot_kind() == Snapshot::kFullAOT) {
const Array& args = Array::Handle(Array::New(1));
diff --git a/runtime/vm/BUILD.gn b/runtime/vm/BUILD.gn
index d7fe4a2..7ab44f4 100644
--- a/runtime/vm/BUILD.gn
+++ b/runtime/vm/BUILD.gn
@@ -71,7 +71,10 @@
if (using_fuchsia_sdk) {
extra_deps += [
"$fuchsia_sdk_root/fidl:fuchsia.deprecatedtimezone",
+ "$fuchsia_sdk_root/pkg:inspect",
+ "$fuchsia_sdk_root/pkg:inspect_service_cpp",
"$fuchsia_sdk_root/pkg:sys_cpp",
+ "$fuchsia_sdk_root/pkg:sys_inspect_cpp",
"$fuchsia_sdk_root/pkg:trace-engine",
]
} else {
@@ -216,9 +219,7 @@
"..:dart_maybe_product_config",
":libdart_vm_config",
]
- sources = [
- "compiler/offsets_extractor.cc",
- ]
+ sources = [ "compiler/offsets_extractor.cc" ]
include_dirs = [ ".." ]
}
@@ -230,8 +231,6 @@
"..:dart_maybe_product_config",
":libdart_vm_config",
]
- sources = [
- "compiler/offsets_extractor.cc",
- ]
+ sources = [ "compiler/offsets_extractor.cc" ]
include_dirs = [ ".." ]
}
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index 65e0dae..8340655 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -317,8 +317,8 @@
V(Int32x4_setFlagZ, 2) \
V(Int32x4_setFlagW, 2) \
V(Int32x4_select, 3) \
- V(Isolate_spawnFunction, 11) \
- V(Isolate_spawnUri, 13) \
+ V(Isolate_spawnFunction, 10) \
+ V(Isolate_spawnUri, 12) \
V(Isolate_getPortAndCapabilitiesOfCurrentIsolate, 0) \
V(Isolate_getCurrentRootUriStr, 0) \
V(Isolate_sendOOB, 2) \
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index 98558ee..5804c37 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -1034,11 +1034,7 @@
s->Push(field->ptr()->initializer_function_);
if (kind != Snapshot::kFullAOT) {
- // Write out the saved initial values
s->Push(field->ptr()->saved_initial_value_);
- }
- if (kind != Snapshot::kFullAOT) {
- // Write out the guarded list length.
s->Push(field->ptr()->guarded_list_length_);
}
if (kind == Snapshot::kFullJIT) {
@@ -1052,7 +1048,8 @@
kind == Snapshot::kFullAOT ||
// Do not reset const fields.
Field::ConstBit::decode(field->ptr()->kind_bits_)) {
- s->Push(s->field_table()->At(field->ptr()->host_offset_or_field_id_));
+ s->Push(s->field_table()->At(
+ Smi::Value(field->ptr()->host_offset_or_field_id_)));
} else {
// Otherwise, for static fields we write out the initial static value.
s->Push(field->ptr()->saved_initial_value_);
@@ -1086,9 +1083,6 @@
WriteField(field, initializer_function_);
if (kind != Snapshot::kFullAOT) {
WriteField(field, saved_initial_value_);
- }
- if (kind != Snapshot::kFullAOT) {
- // Write out the guarded list length.
WriteField(field, guarded_list_length_);
}
if (kind == Snapshot::kFullJIT) {
@@ -1101,9 +1095,7 @@
s->WriteCid(field->ptr()->guarded_cid_);
s->WriteCid(field->ptr()->is_nullable_);
s->Write<int8_t>(field->ptr()->static_type_exactness_state_);
-#if !defined(DART_PRECOMPILED_RUNTIME)
s->Write<uint32_t>(field->ptr()->binary_declaration_);
-#endif
}
s->Write<uint16_t>(field->ptr()->kind_bits_);
@@ -1112,18 +1104,17 @@
if (
// For precompiled static fields, the value was already reset and
// initializer_ now contains a Function.
- // WriteField(field, value_.static_value_);
kind == Snapshot::kFullAOT ||
// Do not reset const fields.
Field::ConstBit::decode(field->ptr()->kind_bits_)) {
- WriteFieldValue(
- "static value",
- s->field_table()->At(field->ptr()->host_offset_or_field_id_));
+ WriteFieldValue("static value",
+ s->field_table()->At(Smi::Value(
+ field->ptr()->host_offset_or_field_id_)));
} else {
// Otherwise, for static fields we write out the initial static value.
WriteFieldValue("static value", field->ptr()->saved_initial_value_);
}
- s->WriteUnsigned(field->ptr()->host_offset_or_field_id_);
+ s->WriteUnsigned(Smi::Value(field->ptr()->host_offset_or_field_id_));
} else {
WriteFieldValue("offset", Smi::New(Field::TargetOffsetOf(field)));
}
@@ -1158,6 +1149,16 @@
Deserializer::InitializeHeader(field, kFieldCid, Field::InstanceSize());
ReadFromTo(field);
if (kind != Snapshot::kFullAOT) {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+ field->ptr()->saved_initial_value_ =
+ static_cast<InstancePtr>(d->ReadRef());
+#endif
+ field->ptr()->guarded_list_length_ = static_cast<SmiPtr>(d->ReadRef());
+ }
+ if (kind == Snapshot::kFullJIT) {
+ field->ptr()->dependent_code_ = static_cast<ArrayPtr>(d->ReadRef());
+ }
+ if (kind != Snapshot::kFullAOT) {
field->ptr()->token_pos_ = d->ReadTokenPosition();
field->ptr()->end_token_pos_ = d->ReadTokenPosition();
field->ptr()->guarded_cid_ = d->ReadCid();
@@ -1174,12 +1175,12 @@
intptr_t field_id = d->ReadUnsigned();
d->field_table()->SetAt(field_id,
static_cast<InstancePtr>(value_or_offset));
- field->ptr()->host_offset_or_field_id_ = field_id;
+ field->ptr()->host_offset_or_field_id_ = Smi::New(field_id);
} else {
- field->ptr()->host_offset_or_field_id_ =
- Smi::Value(Smi::RawCast(value_or_offset));
+ field->ptr()->host_offset_or_field_id_ = Smi::RawCast(value_or_offset);
#if !defined(DART_PRECOMPILED_RUNTIME)
- field->ptr()->target_offset_ = field->ptr()->host_offset_or_field_id_;
+ field->ptr()->target_offset_ =
+ Smi::Value(field->ptr()->host_offset_or_field_id_);
#endif // !defined(DART_PRECOMPILED_RUNTIME)
}
}
diff --git a/runtime/vm/compiler/assembler/assembler_arm.cc b/runtime/vm/compiler/assembler/assembler_arm.cc
index 957457f..df568a3 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm.cc
@@ -3755,6 +3755,15 @@
}
}
+void Assembler::LoadFieldAddressForRegOffset(Register address,
+ Register instance,
+ Register offset_in_words_as_smi) {
+ add(address, instance,
+ Operand(offset_in_words_as_smi, LSL,
+ target::kWordSizeLog2 - kSmiTagShift));
+ AddImmediate(address, -kHeapObjectTag);
+}
+
void Assembler::LoadHalfWordUnaligned(Register dst,
Register addr,
Register tmp) {
diff --git a/runtime/vm/compiler/assembler/assembler_arm.h b/runtime/vm/compiler/assembler/assembler_arm.h
index c45ce98..ebaaf28 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.h
+++ b/runtime/vm/compiler/assembler/assembler_arm.h
@@ -751,6 +751,11 @@
// Branch and link to [base + offset]. Call sequence is never patched.
void BranchLinkOffset(Register base, int32_t offset);
+ void Call(Address target) {
+ ldr(LR, target);
+ blx(LR);
+ }
+
// Add signed immediate value to rd. May clobber IP.
void AddImmediate(Register rd, int32_t value, Condition cond = AL) {
AddImmediate(rd, rd, value, cond);
@@ -1166,6 +1171,10 @@
Register array,
Register index);
+ void LoadFieldAddressForRegOffset(Register address,
+ Register instance,
+ Register offset_in_words_as_smi);
+
void LoadHalfWordUnaligned(Register dst, Register addr, Register tmp);
void LoadHalfWordUnsignedUnaligned(Register dst, Register addr, Register tmp);
void StoreHalfWordUnaligned(Register src, Register addr, Register tmp);
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.cc b/runtime/vm/compiler/assembler/assembler_arm64.cc
index 52b18c2..c0cadfd 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm64.cc
@@ -1281,10 +1281,10 @@
// register within our generated code to avoid the alignment requirement.
// Note that Fuchsia does not have signal handlers.
-void Assembler::SetupDartSP() {
+void Assembler::SetupDartSP(intptr_t reserve /* = 4096 */) {
mov(SP, CSP);
// The caller doesn't have a Thread available. Just kick CSP forward a bit.
- AddImmediate(CSP, CSP, -4096);
+ AddImmediate(CSP, CSP, -Utils::RoundUp(reserve, 16));
}
void Assembler::SetupCSPFromThread(Register thr) {
@@ -1840,6 +1840,15 @@
}
}
+void Assembler::LoadFieldAddressForRegOffset(Register address,
+ Register instance,
+ Register offset_in_words_as_smi) {
+ add(address, instance,
+ Operand(offset_in_words_as_smi, LSL,
+ target::kWordSizeLog2 - kSmiTagShift));
+ AddImmediate(address, -kHeapObjectTag);
+}
+
void Assembler::PushRegisters(const RegisterSet& regs) {
const intptr_t fpu_regs_count = regs.FpuRegisterCount();
if (fpu_regs_count > 0) {
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.h b/runtime/vm/compiler/assembler/assembler_arm64.h
index 4f8f3bd..1b30517 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.h
+++ b/runtime/vm/compiler/assembler/assembler_arm64.h
@@ -472,7 +472,7 @@
void Drop(intptr_t stack_elements) {
ASSERT(stack_elements >= 0);
if (stack_elements > 0) {
- add(SP, SP, Operand(stack_elements * target::kWordSize));
+ AddImmediate(SP, SP, stack_elements * target::kWordSize);
}
}
@@ -1412,6 +1412,11 @@
const Object& equivalence,
CodeEntryKind entry_kind = CodeEntryKind::kNormal);
+ void Call(Address target) {
+ ldr(LR, target);
+ blr(LR);
+ }
+
void AddImmediate(Register dest, int64_t imm) {
AddImmediate(dest, dest, imm);
}
@@ -1578,7 +1583,8 @@
void LoadClassIdMayBeSmi(Register result, Register object);
void LoadTaggedClassIdMayBeSmi(Register result, Register object);
- void SetupDartSP();
+ // Reserve specifies how much space to reserve for the Dart stack.
+ void SetupDartSP(intptr_t reserve = 4096);
void SetupCSPFromThread(Register thr);
void RestoreCSP();
@@ -1711,6 +1717,10 @@
Register array,
Register index);
+ void LoadFieldAddressForRegOffset(Register address,
+ Register instance,
+ Register offset_in_words_as_smi);
+
// Returns object data offset for address calculation; for heap objects also
// accounts for the tag.
static int32_t HeapDataOffset(bool is_external, intptr_t cid) {
diff --git a/runtime/vm/compiler/assembler/assembler_arm64_test.cc b/runtime/vm/compiler/assembler/assembler_arm64_test.cc
index e8c5698..e9fc68c 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64_test.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm64_test.cc
@@ -4556,6 +4556,29 @@
__ ret();
}
+// Push numbers from kMaxPushedNumber to 0 to the stack then drop top
+// kMaxPushedNumber elements. This should leave just kMaxPushedNumber on the
+// stack.
+const intptr_t kMaxPushedNumber = 913;
+
+ASSEMBLER_TEST_GENERATE(Drop, assembler) {
+ __ SetupDartSP((kMaxPushedNumber + 1) * target::kWordSize);
+ for (intptr_t i = kMaxPushedNumber; i >= 0; i--) {
+ __ PushImmediate(i);
+ }
+ __ Drop(kMaxPushedNumber);
+ __ PopRegister(R0);
+ __ RestoreCSP();
+ __ ret();
+}
+
+ASSEMBLER_TEST_RUN(Drop, test) {
+ EXPECT(test != NULL);
+ typedef int64_t (*Int64Return)() DART_UNUSED;
+ EXPECT_EQ(kMaxPushedNumber,
+ EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
+}
+
} // namespace compiler
} // namespace dart
diff --git a/runtime/vm/compiler/assembler/assembler_ia32.h b/runtime/vm/compiler/assembler/assembler_ia32.h
index b487548..f11a048 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32.h
+++ b/runtime/vm/compiler/assembler/assembler_ia32.h
@@ -711,6 +711,8 @@
CodeEntryKind entry_kind = CodeEntryKind::kNormal);
void CallToRuntime();
+ void Call(Address target) { call(target); }
+
void Jmp(const Code& code);
void J(Condition condition, const Code& code);
@@ -746,6 +748,13 @@
Register index,
intptr_t extra_disp = 0);
+ void LoadFieldAddressForRegOffset(Register address,
+ Register instance,
+ Register offset_in_words_as_smi) {
+ static_assert(kSmiTagShift == 1, "adjust scale factor");
+ leal(address, FieldAddress(instance, offset_in_words_as_smi, TIMES_2, 0));
+ }
+
static Address VMTagAddress() {
return Address(THR, target::Thread::vm_tag_offset());
}
diff --git a/runtime/vm/compiler/assembler/assembler_x64.h b/runtime/vm/compiler/assembler/assembler_x64.h
index 8a0d80d..b24b9eb 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.h
+++ b/runtime/vm/compiler/assembler/assembler_x64.h
@@ -733,6 +733,8 @@
const Object& equivalence,
CodeEntryKind entry_kind = CodeEntryKind::kNormal);
+ void Call(Address target) { call(target); }
+
// Unaware of write barrier (use StoreInto* methods for storing to objects).
// TODO(koda): Add StackAddress/HeapAddress types to prevent misuse.
void StoreObject(const Address& dst, const Object& obj);
@@ -977,6 +979,13 @@
Register array,
Register index);
+ void LoadFieldAddressForRegOffset(Register address,
+ Register instance,
+ Register offset_in_words_as_smi) {
+ static_assert(kSmiTagShift == 1, "adjust scale factor");
+ leaq(address, FieldAddress(instance, offset_in_words_as_smi, TIMES_4, 0));
+ }
+
static Address VMTagAddress();
// On some other platforms, we draw a distinction between safe and unsafe
diff --git a/runtime/vm/compiler/assembler/disassembler.cc b/runtime/vm/compiler/assembler/disassembler.cc
index 68b7847..45d4f99 100644
--- a/runtime/vm/compiler/assembler/disassembler.cc
+++ b/runtime/vm/compiler/assembler/disassembler.cc
@@ -241,7 +241,7 @@
ASSERT(code.pointer_offsets_length() == 0);
#endif
- if (FLAG_use_bare_instructions) {
+ if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
THR_Print("(No object pool for bare instructions.)\n");
} else {
const ObjectPool& object_pool =
@@ -458,7 +458,7 @@
code.Disassemble(&formatter);
THR_Print("}\n");
const ObjectPool& object_pool = ObjectPool::Handle(code.object_pool());
- if (FLAG_use_bare_instructions) {
+ if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
THR_Print("(No object pool for bare instructions.)\n");
} else if (!object_pool.IsNull()) {
object_pool.DebugPrint();
diff --git a/runtime/vm/compiler/backend/constant_propagator.cc b/runtime/vm/compiler/backend/constant_propagator.cc
index 7c5a67d..00dbb2d 100644
--- a/runtime/vm/compiler/backend/constant_propagator.cc
+++ b/runtime/vm/compiler/backend/constant_propagator.cc
@@ -856,7 +856,7 @@
const Object& value = def->constant_value();
const AbstractType& checked_type = instr->type();
// If the checked type is a top type, the result is always true.
- if (checked_type.IsTopType()) {
+ if (checked_type.IsTopTypeForInstanceOf()) {
SetValue(instr, Bool::True());
} else if (IsNonConstant(value)) {
intptr_t value_cid = instr->value()->definition()->Type()->ToCid();
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.cc b/runtime/vm/compiler/backend/flow_graph_compiler.cc
index 0532aa3f..a00b77c 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.cc
@@ -2341,7 +2341,7 @@
// test instead of a 6-type test.
AbstractType& bound = AbstractType::Handle(zone(), type_param.bound());
bound = bound.UnwrapFutureOr();
- return !bound.IsTopType() && !bound.IsObjectType() &&
+ return !bound.IsTopTypeForSubtyping() && !bound.IsObjectType() &&
!bound.IsFunctionType() && !bound.IsDartFunctionType() &&
bound.IsType()
? kTestTypeFourArgs
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
index 792d5007..77a9a11 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
@@ -318,7 +318,7 @@
if (type_arguments.Length() == 1) {
const AbstractType& tp_argument =
AbstractType::ZoneHandle(zone(), type_arguments.TypeAt(0));
- if (tp_argument.IsTopType()) {
+ if (tp_argument.IsTopTypeForSubtyping()) {
// Instance class test only necessary.
return GenerateSubtype1TestCacheLookup(
token_pos, type_class, is_instance_lbl, is_not_instance_lbl);
@@ -626,7 +626,7 @@
const AbstractType& type,
LocationSummary* locs) {
ASSERT(type.IsFinalized());
- ASSERT(!type.IsTopType()); // Already checked.
+ ASSERT(!type.IsTopTypeForInstanceOf()); // Already checked.
static_assert(TypeTestABI::kFunctionTypeArgumentsReg <
TypeTestABI::kInstantiatorTypeArgumentsReg,
"Should be ordered to push arguments with one instruction");
@@ -704,7 +704,7 @@
ASSERT(!dst_type.IsNull());
ASSERT(dst_type.IsFinalized());
// Assignable check is skipped in FlowGraphBuilder, not here.
- ASSERT(!dst_type.IsTopTypeForAssignability());
+ ASSERT(!dst_type.IsTopTypeForSubtyping());
if (ShouldUseTypeTestingStubFor(is_optimizing(), dst_type)) {
GenerateAssertAssignableViaTypeTestingStub(
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
index c1f274d..d338e4c 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
@@ -304,7 +304,7 @@
if (type_arguments.Length() == 1) {
const AbstractType& tp_argument =
AbstractType::ZoneHandle(zone(), type_arguments.TypeAt(0));
- if (tp_argument.IsTopType()) {
+ if (tp_argument.IsTopTypeForSubtyping()) {
// Instance class test only necessary.
return GenerateSubtype1TestCacheLookup(
token_pos, type_class, is_instance_lbl, is_not_instance_lbl);
@@ -598,7 +598,7 @@
const AbstractType& type,
LocationSummary* locs) {
ASSERT(type.IsFinalized());
- ASSERT(!type.IsTopType()); // Already checked.
+ ASSERT(!type.IsTopTypeForInstanceOf()); // Already checked.
__ PushPair(TypeTestABI::kFunctionTypeArgumentsReg,
TypeTestABI::kInstantiatorTypeArgumentsReg);
@@ -670,7 +670,7 @@
ASSERT(!dst_type.IsNull());
ASSERT(dst_type.IsFinalized());
// Assignable check is skipped in FlowGraphBuilder, not here.
- ASSERT(!dst_type.IsTopTypeForAssignability());
+ ASSERT(!dst_type.IsTopTypeForSubtyping());
if (ShouldUseTypeTestingStubFor(is_optimizing(), dst_type)) {
GenerateAssertAssignableViaTypeTestingStub(
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
index 20fcd8c..9fbb02c 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
@@ -293,7 +293,7 @@
if (type_arguments.Length() == 1) {
const AbstractType& tp_argument =
AbstractType::ZoneHandle(zone(), type_arguments.TypeAt(0));
- if (tp_argument.IsTopType()) {
+ if (tp_argument.IsTopTypeForSubtyping()) {
// Instance class test only necessary.
return GenerateSubtype1TestCacheLookup(
token_pos, type_class, is_instance_lbl, is_not_instance_lbl);
@@ -597,7 +597,7 @@
const AbstractType& type,
LocationSummary* locs) {
ASSERT(type.IsFinalized());
- ASSERT(!type.IsTopType()); // Already checked.
+ ASSERT(!type.IsTopTypeForInstanceOf()); // Already checked.
__ pushl(EDX); // Store instantiator type arguments.
__ pushl(ECX); // Store function type arguments.
@@ -680,7 +680,7 @@
ASSERT(!dst_type.IsNull());
ASSERT(dst_type.IsFinalized());
// Assignable check is skipped in FlowGraphBuilder, not here.
- ASSERT(!dst_type.IsTopTypeForAssignability());
+ ASSERT(!dst_type.IsTopTypeForSubtyping());
__ pushl(TypeTestABI::kInstantiatorTypeArgumentsReg);
__ pushl(TypeTestABI::kFunctionTypeArgumentsReg);
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
index cefc349..e6502dd 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
@@ -316,7 +316,7 @@
if (type_arguments.Length() == 1) {
const AbstractType& tp_argument =
AbstractType::ZoneHandle(zone(), type_arguments.TypeAt(0));
- if (tp_argument.IsTopType()) {
+ if (tp_argument.IsTopTypeForSubtyping()) {
// Instance class test only necessary.
return GenerateSubtype1TestCacheLookup(
token_pos, type_class, is_instance_lbl, is_not_instance_lbl);
@@ -620,7 +620,7 @@
const AbstractType& type,
LocationSummary* locs) {
ASSERT(type.IsFinalized());
- ASSERT(!type.IsTopType()); // Already checked.
+ ASSERT(!type.IsTopTypeForInstanceOf()); // Already checked.
compiler::Label is_instance, is_not_instance;
// 'null' is an instance of Null, Object*, Never*, void, and dynamic.
@@ -685,7 +685,7 @@
ASSERT(!dst_type.IsNull());
ASSERT(dst_type.IsFinalized());
// Assignable check is skipped in FlowGraphBuilder, not here.
- ASSERT(!dst_type.IsTopTypeForAssignability());
+ ASSERT(!dst_type.IsTopTypeForSubtyping());
if (ShouldUseTypeTestingStubFor(is_optimizing(), dst_type)) {
GenerateAssertAssignableViaTypeTestingStub(
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index 3231fb8..a37b4ef 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -2949,7 +2949,7 @@
instantiator_type_arguments()->BindTo(flow_graph->constant_null());
function_type_arguments()->BindTo(flow_graph->constant_null());
- if (new_dst_type.IsTopTypeForAssignability() ||
+ if (new_dst_type.IsTopTypeForSubtyping() ||
(FLAG_eliminate_type_checks &&
value()->Type()->IsAssignableTo(new_dst_type))) {
return value()->definition();
@@ -3246,8 +3246,8 @@
const AbstractType& unwrapped_type =
AbstractType::Handle(type->ToAbstractType()->UnwrapFutureOr());
// Note that type 'Number' is a subtype of itself.
- return unwrapped_type.IsTopType() || unwrapped_type.IsObjectType() ||
- unwrapped_type.IsTypeParameter() ||
+ return unwrapped_type.IsTopTypeForSubtyping() ||
+ unwrapped_type.IsObjectType() || unwrapped_type.IsTypeParameter() ||
unwrapped_type.IsSubtypeOf(Type::Handle(Type::Number()), Heap::kOld);
}
@@ -4110,8 +4110,30 @@
__ LoadObject(InitInstanceFieldABI::kFieldReg,
Field::ZoneHandle(field().Original()));
- const auto& stub = Code::ZoneHandle(
- compiler->isolate()->object_store()->init_instance_field_stub());
+
+ auto object_store = compiler->isolate()->object_store();
+ auto& stub = Code::ZoneHandle(compiler->zone());
+ if (field().needs_load_guard()) {
+ stub = object_store->init_instance_field_stub();
+ } else if (field().is_late()) {
+ if (!field().has_nontrivial_initializer()) {
+ // Common stub calls runtime which will throw an exception.
+ stub = object_store->init_instance_field_stub();
+ } else {
+ // Stubs for late field initialization call initializer
+ // function directly, so make sure one is created.
+ field().EnsureInitializerFunction();
+
+ if (field().is_final()) {
+ stub = object_store->init_late_final_instance_field_stub();
+ } else {
+ stub = object_store->init_late_instance_field_stub();
+ }
+ }
+ } else {
+ UNREACHABLE();
+ }
+
// Instruction inputs are popped from the stack at this point,
// so deoptimization environment has to be adjusted.
// This adjustment is done in FlowGraph::AttachEnvironment.
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index 7bdedf6..4612792 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -6356,6 +6356,11 @@
virtual bool HasUnknownSideEffects() const { return true; }
virtual Instruction* Canonicalize(FlowGraph* flow_graph);
+ virtual bool AllowsCSE() const { return true; }
+ virtual bool AttributesEqual(Instruction* other) const {
+ return other->AsInitInstanceField()->field().raw() == field().raw();
+ }
+
private:
const Field& field_;
diff --git a/runtime/vm/compiler/backend/type_propagator.cc b/runtime/vm/compiler/backend/type_propagator.cc
index dc47a68..81d0f03 100644
--- a/runtime/vm/compiler/backend/type_propagator.cc
+++ b/runtime/vm/compiler/backend/type_propagator.cc
@@ -416,7 +416,7 @@
type = &(instance_of->type());
left = instance_of->value()->definition();
}
- if (!type->IsTopType()) {
+ if (!type->IsTopTypeForInstanceOf()) {
const bool is_nullable = (type->IsNullable() || type->IsTypeParameter() ||
(type->IsNeverType() && type->IsLegacy()))
? CompileType::kNullable
@@ -804,7 +804,7 @@
}
bool CompileType::IsSubtypeOf(const AbstractType& other) {
- if (other.IsTopType()) {
+ if (other.IsTopTypeForSubtyping()) {
return true;
}
@@ -816,7 +816,7 @@
}
bool CompileType::IsAssignableTo(const AbstractType& other) {
- if (other.IsTopTypeForAssignability()) {
+ if (other.IsTopTypeForSubtyping()) {
return true;
}
if (IsNone()) {
@@ -829,7 +829,7 @@
}
bool CompileType::IsInstanceOf(const AbstractType& other) {
- if (other.IsTopType()) {
+ if (other.IsTopTypeForInstanceOf()) {
return true;
}
if (IsNone() || !other.IsInstantiated()) {
diff --git a/runtime/vm/compiler/call_specializer.cc b/runtime/vm/compiler/call_specializer.cc
index cabdb7c..750c41d 100644
--- a/runtime/vm/compiler/call_specializer.cc
+++ b/runtime/vm/compiler/call_specializer.cc
@@ -741,10 +741,6 @@
if (field.needs_load_guard()) {
return false;
}
- if (field.is_late()) {
- // TODO(http://dartbug.com/40447): Inline implicit getters for late fields.
- return false;
- }
if (should_clone_fields_) {
field = field.CloneFromOriginal();
}
@@ -770,9 +766,19 @@
void CallSpecializer::InlineImplicitInstanceGetter(Definition* call,
const Field& field) {
+ ASSERT(field.is_instance());
+ Definition* receiver = call->ArgumentAt(0);
+
+ if (field.NeedsInitializationCheckOnLoad()) {
+ InsertBefore(call,
+ new (Z) InitInstanceFieldInstr(new (Z) Value(receiver), field,
+ call->deopt_id()),
+ call->env(), FlowGraph::kEffect);
+ }
+
const Slot& slot = Slot::Get(field, &flow_graph()->parsed_function());
- LoadFieldInstr* load = new (Z) LoadFieldInstr(
- new (Z) Value(call->ArgumentAt(0)), slot, call->token_pos());
+ LoadFieldInstr* load =
+ new (Z) LoadFieldInstr(new (Z) Value(receiver), slot, call->token_pos());
// Discard the environment from the original instruction because the load
// can't deoptimize.
@@ -861,7 +867,7 @@
// Build an AssertAssignable if necessary.
const AbstractType& dst_type = AbstractType::ZoneHandle(zone(), field.type());
- if (I->argument_type_checks() && !dst_type.IsTopTypeForAssignability()) {
+ if (I->argument_type_checks() && !dst_type.IsTopTypeForSubtyping()) {
// Compute if we need to type check the value. Always type check if
// at a dynamic invocation.
bool needs_check = true;
@@ -1109,7 +1115,8 @@
const AbstractType& unwrapped_type =
AbstractType::Handle(type.UnwrapFutureOr());
ASSERT(unwrapped_type.IsInstantiated());
- is_subtype = unwrapped_type.IsTopType() || unwrapped_type.IsNullable() ||
+ is_subtype = unwrapped_type.IsTopTypeForInstanceOf() ||
+ unwrapped_type.IsNullable() ||
(unwrapped_type.IsLegacy() && unwrapped_type.IsNeverType());
} else {
is_subtype =
@@ -1177,7 +1184,8 @@
return false;
}
}
- if (type.IsNullable() || type.IsTopType() || type.IsNeverType()) {
+ if (type.IsNullable() || type.IsTopTypeForInstanceOf() ||
+ type.IsNeverType()) {
// A class id check is not sufficient, since a null instance also satisfies
// the test against a nullable type.
// TODO(regis): Add a null check in addition to the class id check?
diff --git a/runtime/vm/compiler/frontend/bytecode_reader.cc b/runtime/vm/compiler/frontend/bytecode_reader.cc
index 4b10135..9295cb6 100644
--- a/runtime/vm/compiler/frontend/bytecode_reader.cc
+++ b/runtime/vm/compiler/frontend/bytecode_reader.cc
@@ -395,7 +395,8 @@
for (intptr_t i = 0, n = type_params.Length(); i < n; ++i) {
type_param ^= type_params.TypeAt(i);
bound = type_param.bound();
- if (!bound.IsTopType() && !type_param.IsGenericCovariantImpl()) {
+ if (!bound.IsTopTypeForSubtyping() &&
+ !type_param.IsGenericCovariantImpl()) {
name = type_param.name();
ASSERT(type_param.IsFinalized());
check = ParameterTypeCheck::New();
@@ -421,7 +422,7 @@
const bool has_optional_parameters = function.HasOptionalParameters();
for (intptr_t i = function.NumImplicitParameters(); i < num_params; ++i) {
type = function.ParameterTypeAt(i);
- if (!type.IsTopTypeForAssignability() &&
+ if (!type.IsTopTypeForSubtyping() &&
!is_generic_covariant_impl.Contains(i) && !is_covariant.Contains(i)) {
name = function.ParameterNameAt(i);
intptr_t index;
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index 4dcc794..3079ccf 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -3671,7 +3671,7 @@
// The VM does not like an instanceOf call with a dynamic type. We need to
// special case this situation by detecting a top type.
- if (type.IsTopType()) {
+ if (type.IsTopTypeForInstanceOf()) {
// Evaluate the expression on the left but ignore its result.
instructions += Drop();
@@ -3718,7 +3718,7 @@
Fragment instructions = BuildExpression(); // read operand.
const AbstractType& type = T.BuildType(); // read type.
- if (type.IsInstantiated() && type.IsTopTypeForAssignability()) {
+ if (type.IsInstantiated() && type.IsTopTypeForSubtyping()) {
// We already evaluated the operand on the left and just leave it there as
// the result of the `obj as dynamic` expression.
} else {
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index 63e8987..de87175 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -1537,7 +1537,7 @@
if (!I->should_emit_strong_mode_checks()) {
return Fragment();
}
- if (!dst_type.IsTopTypeForAssignability()) {
+ if (!dst_type.IsTopTypeForSubtyping()) {
LocalVariable* top_of_stack = MakeTemporary();
instructions += LoadLocal(top_of_stack);
instructions += AssertAssignableLoadTypeArguments(TokenPosition::kNoSource,
@@ -1628,7 +1628,7 @@
type_param ^= type_parameters.TypeAt(i);
bound = type_param.bound();
- if (bound.IsTopType()) {
+ if (bound.IsTopTypeForSubtyping()) {
continue;
}
@@ -1685,7 +1685,7 @@
&AbstractType::ZoneHandle(Z, forwarding_target->ParameterTypeAt(i));
}
- if (target_type->IsTopTypeForAssignability()) continue;
+ if (target_type->IsTopTypeForSubtyping()) continue;
const bool is_covariant = param->is_explicit_covariant_parameter();
Fragment* checks = is_covariant ? explicit_checks : implicit_checks;
@@ -2254,7 +2254,7 @@
body += Drop(); // argument count
AbstractType& return_type = AbstractType::Handle(function.result_type());
- if (!return_type.IsTopTypeForAssignability()) {
+ if (!return_type.IsTopTypeForSubtyping()) {
body += AssertAssignableLoadTypeArguments(TokenPosition::kNoSource,
return_type, Symbols::Empty());
}
diff --git a/runtime/vm/compiler/runtime_api.cc b/runtime/vm/compiler/runtime_api.cc
index 45f0cf8..7c9f60a 100644
--- a/runtime/vm/compiler/runtime_api.cc
+++ b/runtime/vm/compiler/runtime_api.cc
@@ -127,6 +127,10 @@
return Object::null_object();
}
+const Object& SentinelObject() {
+ return Object::sentinel();
+}
+
const Bool& TrueObject() {
return dart::Bool::True();
}
diff --git a/runtime/vm/compiler/runtime_api.h b/runtime/vm/compiler/runtime_api.h
index 5c6fcaf..3e024c0 100644
--- a/runtime/vm/compiler/runtime_api.h
+++ b/runtime/vm/compiler/runtime_api.h
@@ -96,6 +96,7 @@
//
const Object& NullObject();
+const Object& SentinelObject();
const Bool& TrueObject();
const Bool& FalseObject();
const Object& EmptyTypeArguments();
@@ -1245,8 +1246,9 @@
static word guarded_list_length_in_object_offset_offset();
static word guarded_list_length_offset();
static word is_nullable_offset();
- static word static_value_offset();
static word kind_bits_offset();
+ static word initializer_function_offset();
+ static word host_offset_or_field_id_offset();
static word InstanceSize();
static word NextFieldOffset();
};
diff --git a/runtime/vm/compiler/runtime_offsets_extracted.h b/runtime/vm/compiler/runtime_offsets_extracted.h
index 67b096c..a575006 100644
--- a/runtime/vm/compiler/runtime_offsets_extracted.h
+++ b/runtime/vm/compiler/runtime_offsets_extracted.h
@@ -104,13 +104,17 @@
ExternalTwoByteString_external_data_offset = 12;
static constexpr dart::compiler::target::word Float32x4_value_offset = 8;
static constexpr dart::compiler::target::word Float64x2_value_offset = 8;
-static constexpr dart::compiler::target::word Field_guarded_cid_offset = 44;
static constexpr dart::compiler::target::word
- Field_guarded_list_length_in_object_offset_offset = 52;
+ Field_initializer_function_offset = 16;
+static constexpr dart::compiler::target::word
+ Field_host_offset_or_field_id_offset = 20;
+static constexpr dart::compiler::target::word Field_guarded_cid_offset = 48;
+static constexpr dart::compiler::target::word
+ Field_guarded_list_length_in_object_offset_offset = 56;
static constexpr dart::compiler::target::word Field_guarded_list_length_offset =
- 24;
-static constexpr dart::compiler::target::word Field_is_nullable_offset = 46;
-static constexpr dart::compiler::target::word Field_kind_bits_offset = 54;
+ 28;
+static constexpr dart::compiler::target::word Field_is_nullable_offset = 50;
+static constexpr dart::compiler::target::word Field_kind_bits_offset = 58;
static constexpr dart::compiler::target::word Function_code_offset = 44;
static constexpr dart::compiler::target::word Function_entry_point_offset[] = {
4, 8};
@@ -193,9 +197,9 @@
static constexpr dart::compiler::target::word
Thread_AllocateArray_entry_point_offset = 368;
static constexpr dart::compiler::target::word Thread_active_exception_offset =
- 688;
-static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
692;
+static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
+ 696;
static constexpr dart::compiler::target::word
Thread_array_write_barrier_code_offset = 128;
static constexpr dart::compiler::target::word
@@ -232,7 +236,7 @@
Thread_call_to_runtime_entry_point_offset = 264;
static constexpr dart::compiler::target::word
Thread_call_to_runtime_stub_offset = 148;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 724;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 728;
static constexpr dart::compiler::target::word
Thread_dispatch_table_array_offset = 48;
static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
@@ -250,7 +254,7 @@
static constexpr dart::compiler::target::word
Thread_enter_safepoint_stub_offset = 244;
static constexpr dart::compiler::target::word Thread_execution_state_offset =
- 708;
+ 712;
static constexpr dart::compiler::target::word
Thread_exit_safepoint_stub_offset = 248;
static constexpr dart::compiler::target::word
@@ -270,7 +274,7 @@
static constexpr dart::compiler::target::word
Thread_float_zerow_address_offset = 364;
static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
- 696;
+ 700;
static constexpr dart::compiler::target::word
Thread_interpret_call_entry_point_offset = 332;
static constexpr dart::compiler::target::word
@@ -311,11 +315,11 @@
static constexpr dart::compiler::target::word Thread_object_null_offset = 112;
static constexpr dart::compiler::target::word
Thread_predefined_symbols_address_offset = 336;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 700;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 704;
static constexpr dart::compiler::target::word
- Thread_saved_shadow_call_stack_offset = 704;
+ Thread_saved_shadow_call_stack_offset = 708;
static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
- 712;
+ 716;
static constexpr dart::compiler::target::word
Thread_slow_type_test_stub_offset = 236;
static constexpr dart::compiler::target::word
@@ -348,7 +352,7 @@
Thread_write_barrier_entry_point_offset = 256;
static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
40;
-static constexpr dart::compiler::target::word Thread_callback_code_offset = 716;
+static constexpr dart::compiler::target::word Thread_callback_code_offset = 720;
static constexpr dart::compiler::target::word TimelineStream_enabled_offset = 8;
static constexpr dart::compiler::target::word TwoByteString_data_offset = 12;
static constexpr dart::compiler::target::word Type_arguments_offset = 16;
@@ -386,7 +390,7 @@
4, 12, 8, 16};
static constexpr dart::compiler::target::word
Thread_write_barrier_wrappers_thread_offset[] = {
- 656, 660, 664, 668, 672, -1, 676, -1, 680, 684, -1, -1, -1, -1, -1, -1};
+ 660, 664, 668, 672, 676, -1, 680, -1, 684, 688, -1, -1, -1, -1, -1, -1};
static constexpr dart::compiler::target::word ApiError_InstanceSize = 8;
static constexpr dart::compiler::target::word Array_InstanceSize = 12;
static constexpr dart::compiler::target::word Array_header_size = 12;
@@ -581,13 +585,17 @@
ExternalTwoByteString_external_data_offset = 16;
static constexpr dart::compiler::target::word Float32x4_value_offset = 8;
static constexpr dart::compiler::target::word Float64x2_value_offset = 8;
-static constexpr dart::compiler::target::word Field_guarded_cid_offset = 80;
static constexpr dart::compiler::target::word
- Field_guarded_list_length_in_object_offset_offset = 88;
+ Field_initializer_function_offset = 32;
+static constexpr dart::compiler::target::word
+ Field_host_offset_or_field_id_offset = 40;
+static constexpr dart::compiler::target::word Field_guarded_cid_offset = 88;
+static constexpr dart::compiler::target::word
+ Field_guarded_list_length_in_object_offset_offset = 96;
static constexpr dart::compiler::target::word Field_guarded_list_length_offset =
- 48;
-static constexpr dart::compiler::target::word Field_is_nullable_offset = 82;
-static constexpr dart::compiler::target::word Field_kind_bits_offset = 90;
+ 56;
+static constexpr dart::compiler::target::word Field_is_nullable_offset = 90;
+static constexpr dart::compiler::target::word Field_kind_bits_offset = 98;
static constexpr dart::compiler::target::word Function_code_offset = 88;
static constexpr dart::compiler::target::word Function_entry_point_offset[] = {
8, 16};
@@ -671,9 +679,9 @@
static constexpr dart::compiler::target::word
Thread_AllocateArray_entry_point_offset = 720;
static constexpr dart::compiler::target::word Thread_active_exception_offset =
- 1384;
-static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
1392;
+static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
+ 1400;
static constexpr dart::compiler::target::word
Thread_array_write_barrier_code_offset = 240;
static constexpr dart::compiler::target::word
@@ -710,7 +718,7 @@
Thread_call_to_runtime_entry_point_offset = 512;
static constexpr dart::compiler::target::word
Thread_call_to_runtime_stub_offset = 280;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1456;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1464;
static constexpr dart::compiler::target::word
Thread_dispatch_table_array_offset = 96;
static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
@@ -728,7 +736,7 @@
static constexpr dart::compiler::target::word
Thread_enter_safepoint_stub_offset = 472;
static constexpr dart::compiler::target::word Thread_execution_state_offset =
- 1424;
+ 1432;
static constexpr dart::compiler::target::word
Thread_exit_safepoint_stub_offset = 480;
static constexpr dart::compiler::target::word
@@ -748,7 +756,7 @@
static constexpr dart::compiler::target::word
Thread_float_zerow_address_offset = 712;
static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
- 1400;
+ 1408;
static constexpr dart::compiler::target::word
Thread_interpret_call_entry_point_offset = 648;
static constexpr dart::compiler::target::word
@@ -789,11 +797,11 @@
static constexpr dart::compiler::target::word Thread_object_null_offset = 208;
static constexpr dart::compiler::target::word
Thread_predefined_symbols_address_offset = 656;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1408;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1416;
static constexpr dart::compiler::target::word
- Thread_saved_shadow_call_stack_offset = 1416;
+ Thread_saved_shadow_call_stack_offset = 1424;
static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
- 1432;
+ 1440;
static constexpr dart::compiler::target::word
Thread_slow_type_test_stub_offset = 456;
static constexpr dart::compiler::target::word
@@ -827,7 +835,7 @@
static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
80;
static constexpr dart::compiler::target::word Thread_callback_code_offset =
- 1440;
+ 1448;
static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
16;
static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
@@ -866,8 +874,8 @@
8, 24, 16, 32};
static constexpr dart::compiler::target::word
Thread_write_barrier_wrappers_thread_offset[] = {
- 1296, 1304, 1312, 1320, -1, -1, 1328, 1336,
- 1344, 1352, 1360, -1, 1368, 1376, -1, -1};
+ 1304, 1312, 1320, 1328, -1, -1, 1336, 1344,
+ 1352, 1360, 1368, -1, 1376, 1384, -1, -1};
static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
static constexpr dart::compiler::target::word Array_InstanceSize = 24;
static constexpr dart::compiler::target::word Array_header_size = 24;
@@ -898,7 +906,7 @@
24;
static constexpr dart::compiler::target::word FfiTrampolineData_InstanceSize =
48;
-static constexpr dart::compiler::target::word Field_InstanceSize = 112;
+static constexpr dart::compiler::target::word Field_InstanceSize = 104;
static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
static constexpr dart::compiler::target::word Function_InstanceSize = 152;
@@ -1061,13 +1069,17 @@
ExternalTwoByteString_external_data_offset = 12;
static constexpr dart::compiler::target::word Float32x4_value_offset = 8;
static constexpr dart::compiler::target::word Float64x2_value_offset = 8;
-static constexpr dart::compiler::target::word Field_guarded_cid_offset = 44;
static constexpr dart::compiler::target::word
- Field_guarded_list_length_in_object_offset_offset = 52;
+ Field_initializer_function_offset = 16;
+static constexpr dart::compiler::target::word
+ Field_host_offset_or_field_id_offset = 20;
+static constexpr dart::compiler::target::word Field_guarded_cid_offset = 48;
+static constexpr dart::compiler::target::word
+ Field_guarded_list_length_in_object_offset_offset = 56;
static constexpr dart::compiler::target::word Field_guarded_list_length_offset =
- 24;
-static constexpr dart::compiler::target::word Field_is_nullable_offset = 46;
-static constexpr dart::compiler::target::word Field_kind_bits_offset = 54;
+ 28;
+static constexpr dart::compiler::target::word Field_is_nullable_offset = 50;
+static constexpr dart::compiler::target::word Field_kind_bits_offset = 58;
static constexpr dart::compiler::target::word Function_code_offset = 44;
static constexpr dart::compiler::target::word Function_entry_point_offset[] = {
4, 8};
@@ -1150,9 +1162,9 @@
static constexpr dart::compiler::target::word
Thread_AllocateArray_entry_point_offset = 368;
static constexpr dart::compiler::target::word Thread_active_exception_offset =
- 656;
-static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
660;
+static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
+ 664;
static constexpr dart::compiler::target::word
Thread_array_write_barrier_code_offset = 128;
static constexpr dart::compiler::target::word
@@ -1189,7 +1201,7 @@
Thread_call_to_runtime_entry_point_offset = 264;
static constexpr dart::compiler::target::word
Thread_call_to_runtime_stub_offset = 148;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 692;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 696;
static constexpr dart::compiler::target::word
Thread_dispatch_table_array_offset = 48;
static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
@@ -1207,7 +1219,7 @@
static constexpr dart::compiler::target::word
Thread_enter_safepoint_stub_offset = 244;
static constexpr dart::compiler::target::word Thread_execution_state_offset =
- 676;
+ 680;
static constexpr dart::compiler::target::word
Thread_exit_safepoint_stub_offset = 248;
static constexpr dart::compiler::target::word
@@ -1227,7 +1239,7 @@
static constexpr dart::compiler::target::word
Thread_float_zerow_address_offset = 364;
static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
- 664;
+ 668;
static constexpr dart::compiler::target::word
Thread_interpret_call_entry_point_offset = 332;
static constexpr dart::compiler::target::word
@@ -1268,11 +1280,11 @@
static constexpr dart::compiler::target::word Thread_object_null_offset = 112;
static constexpr dart::compiler::target::word
Thread_predefined_symbols_address_offset = 336;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 668;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 672;
static constexpr dart::compiler::target::word
- Thread_saved_shadow_call_stack_offset = 672;
+ Thread_saved_shadow_call_stack_offset = 676;
static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
- 680;
+ 684;
static constexpr dart::compiler::target::word
Thread_slow_type_test_stub_offset = 236;
static constexpr dart::compiler::target::word
@@ -1305,7 +1317,7 @@
Thread_write_barrier_entry_point_offset = 256;
static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
40;
-static constexpr dart::compiler::target::word Thread_callback_code_offset = 684;
+static constexpr dart::compiler::target::word Thread_callback_code_offset = 688;
static constexpr dart::compiler::target::word TimelineStream_enabled_offset = 8;
static constexpr dart::compiler::target::word TwoByteString_data_offset = 12;
static constexpr dart::compiler::target::word Type_arguments_offset = 16;
@@ -1535,13 +1547,17 @@
ExternalTwoByteString_external_data_offset = 16;
static constexpr dart::compiler::target::word Float32x4_value_offset = 8;
static constexpr dart::compiler::target::word Float64x2_value_offset = 8;
-static constexpr dart::compiler::target::word Field_guarded_cid_offset = 80;
static constexpr dart::compiler::target::word
- Field_guarded_list_length_in_object_offset_offset = 88;
+ Field_initializer_function_offset = 32;
+static constexpr dart::compiler::target::word
+ Field_host_offset_or_field_id_offset = 40;
+static constexpr dart::compiler::target::word Field_guarded_cid_offset = 88;
+static constexpr dart::compiler::target::word
+ Field_guarded_list_length_in_object_offset_offset = 96;
static constexpr dart::compiler::target::word Field_guarded_list_length_offset =
- 48;
-static constexpr dart::compiler::target::word Field_is_nullable_offset = 82;
-static constexpr dart::compiler::target::word Field_kind_bits_offset = 90;
+ 56;
+static constexpr dart::compiler::target::word Field_is_nullable_offset = 90;
+static constexpr dart::compiler::target::word Field_kind_bits_offset = 98;
static constexpr dart::compiler::target::word Function_code_offset = 88;
static constexpr dart::compiler::target::word Function_entry_point_offset[] = {
8, 16};
@@ -1625,9 +1641,9 @@
static constexpr dart::compiler::target::word
Thread_AllocateArray_entry_point_offset = 720;
static constexpr dart::compiler::target::word Thread_active_exception_offset =
- 1456;
-static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
1464;
+static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
+ 1472;
static constexpr dart::compiler::target::word
Thread_array_write_barrier_code_offset = 240;
static constexpr dart::compiler::target::word
@@ -1664,7 +1680,7 @@
Thread_call_to_runtime_entry_point_offset = 512;
static constexpr dart::compiler::target::word
Thread_call_to_runtime_stub_offset = 280;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1528;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1536;
static constexpr dart::compiler::target::word
Thread_dispatch_table_array_offset = 96;
static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
@@ -1682,7 +1698,7 @@
static constexpr dart::compiler::target::word
Thread_enter_safepoint_stub_offset = 472;
static constexpr dart::compiler::target::word Thread_execution_state_offset =
- 1496;
+ 1504;
static constexpr dart::compiler::target::word
Thread_exit_safepoint_stub_offset = 480;
static constexpr dart::compiler::target::word
@@ -1702,7 +1718,7 @@
static constexpr dart::compiler::target::word
Thread_float_zerow_address_offset = 712;
static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
- 1472;
+ 1480;
static constexpr dart::compiler::target::word
Thread_interpret_call_entry_point_offset = 648;
static constexpr dart::compiler::target::word
@@ -1743,11 +1759,11 @@
static constexpr dart::compiler::target::word Thread_object_null_offset = 208;
static constexpr dart::compiler::target::word
Thread_predefined_symbols_address_offset = 656;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1480;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1488;
static constexpr dart::compiler::target::word
- Thread_saved_shadow_call_stack_offset = 1488;
+ Thread_saved_shadow_call_stack_offset = 1496;
static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
- 1504;
+ 1512;
static constexpr dart::compiler::target::word
Thread_slow_type_test_stub_offset = 456;
static constexpr dart::compiler::target::word
@@ -1781,7 +1797,7 @@
static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
80;
static constexpr dart::compiler::target::word Thread_callback_code_offset =
- 1512;
+ 1520;
static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
16;
static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
@@ -1820,9 +1836,9 @@
8, 24, 16, 32};
static constexpr dart::compiler::target::word
Thread_write_barrier_wrappers_thread_offset[] = {
- 1296, 1304, 1312, 1320, 1328, 1336, 1344, 1352, 1360, 1368, 1376,
- 1384, 1392, 1400, 1408, -1, -1, -1, -1, 1416, 1424, -1,
- -1, 1432, 1440, 1448, -1, -1, -1, -1, -1, -1};
+ 1304, 1312, 1320, 1328, 1336, 1344, 1352, 1360, 1368, 1376, 1384,
+ 1392, 1400, 1408, 1416, -1, -1, -1, -1, 1424, 1432, -1,
+ -1, 1440, 1448, 1456, -1, -1, -1, -1, -1, -1};
static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
static constexpr dart::compiler::target::word Array_InstanceSize = 24;
static constexpr dart::compiler::target::word Array_header_size = 24;
@@ -1853,7 +1869,7 @@
24;
static constexpr dart::compiler::target::word FfiTrampolineData_InstanceSize =
48;
-static constexpr dart::compiler::target::word Field_InstanceSize = 112;
+static constexpr dart::compiler::target::word Field_InstanceSize = 104;
static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
static constexpr dart::compiler::target::word Function_InstanceSize = 152;
@@ -2016,13 +2032,17 @@
ExternalTwoByteString_external_data_offset = 12;
static constexpr dart::compiler::target::word Float32x4_value_offset = 8;
static constexpr dart::compiler::target::word Float64x2_value_offset = 8;
-static constexpr dart::compiler::target::word Field_guarded_cid_offset = 44;
static constexpr dart::compiler::target::word
- Field_guarded_list_length_in_object_offset_offset = 52;
+ Field_initializer_function_offset = 16;
+static constexpr dart::compiler::target::word
+ Field_host_offset_or_field_id_offset = 20;
+static constexpr dart::compiler::target::word Field_guarded_cid_offset = 48;
+static constexpr dart::compiler::target::word
+ Field_guarded_list_length_in_object_offset_offset = 56;
static constexpr dart::compiler::target::word Field_guarded_list_length_offset =
- 24;
-static constexpr dart::compiler::target::word Field_is_nullable_offset = 46;
-static constexpr dart::compiler::target::word Field_kind_bits_offset = 54;
+ 28;
+static constexpr dart::compiler::target::word Field_is_nullable_offset = 50;
+static constexpr dart::compiler::target::word Field_kind_bits_offset = 58;
static constexpr dart::compiler::target::word Function_code_offset = 44;
static constexpr dart::compiler::target::word Function_entry_point_offset[] = {
4, 8};
@@ -2104,9 +2124,9 @@
static constexpr dart::compiler::target::word
Thread_AllocateArray_entry_point_offset = 368;
static constexpr dart::compiler::target::word Thread_active_exception_offset =
- 688;
-static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
692;
+static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
+ 696;
static constexpr dart::compiler::target::word
Thread_array_write_barrier_code_offset = 128;
static constexpr dart::compiler::target::word
@@ -2143,7 +2163,7 @@
Thread_call_to_runtime_entry_point_offset = 264;
static constexpr dart::compiler::target::word
Thread_call_to_runtime_stub_offset = 148;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 724;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 728;
static constexpr dart::compiler::target::word
Thread_dispatch_table_array_offset = 48;
static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
@@ -2161,7 +2181,7 @@
static constexpr dart::compiler::target::word
Thread_enter_safepoint_stub_offset = 244;
static constexpr dart::compiler::target::word Thread_execution_state_offset =
- 708;
+ 712;
static constexpr dart::compiler::target::word
Thread_exit_safepoint_stub_offset = 248;
static constexpr dart::compiler::target::word
@@ -2181,7 +2201,7 @@
static constexpr dart::compiler::target::word
Thread_float_zerow_address_offset = 364;
static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
- 696;
+ 700;
static constexpr dart::compiler::target::word
Thread_interpret_call_entry_point_offset = 332;
static constexpr dart::compiler::target::word
@@ -2222,11 +2242,11 @@
static constexpr dart::compiler::target::word Thread_object_null_offset = 112;
static constexpr dart::compiler::target::word
Thread_predefined_symbols_address_offset = 336;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 700;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 704;
static constexpr dart::compiler::target::word
- Thread_saved_shadow_call_stack_offset = 704;
+ Thread_saved_shadow_call_stack_offset = 708;
static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
- 712;
+ 716;
static constexpr dart::compiler::target::word
Thread_slow_type_test_stub_offset = 236;
static constexpr dart::compiler::target::word
@@ -2259,7 +2279,7 @@
Thread_write_barrier_entry_point_offset = 256;
static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
40;
-static constexpr dart::compiler::target::word Thread_callback_code_offset = 716;
+static constexpr dart::compiler::target::word Thread_callback_code_offset = 720;
static constexpr dart::compiler::target::word TimelineStream_enabled_offset = 8;
static constexpr dart::compiler::target::word TwoByteString_data_offset = 12;
static constexpr dart::compiler::target::word Type_arguments_offset = 16;
@@ -2294,7 +2314,7 @@
4, 12, 8, 16};
static constexpr dart::compiler::target::word
Thread_write_barrier_wrappers_thread_offset[] = {
- 656, 660, 664, 668, 672, -1, 676, -1, 680, 684, -1, -1, -1, -1, -1, -1};
+ 660, 664, 668, 672, 676, -1, 680, -1, 684, 688, -1, -1, -1, -1, -1, -1};
static constexpr dart::compiler::target::word ApiError_InstanceSize = 8;
static constexpr dart::compiler::target::word Array_InstanceSize = 12;
static constexpr dart::compiler::target::word Array_header_size = 12;
@@ -2487,13 +2507,17 @@
ExternalTwoByteString_external_data_offset = 16;
static constexpr dart::compiler::target::word Float32x4_value_offset = 8;
static constexpr dart::compiler::target::word Float64x2_value_offset = 8;
-static constexpr dart::compiler::target::word Field_guarded_cid_offset = 80;
static constexpr dart::compiler::target::word
- Field_guarded_list_length_in_object_offset_offset = 88;
+ Field_initializer_function_offset = 32;
+static constexpr dart::compiler::target::word
+ Field_host_offset_or_field_id_offset = 40;
+static constexpr dart::compiler::target::word Field_guarded_cid_offset = 88;
+static constexpr dart::compiler::target::word
+ Field_guarded_list_length_in_object_offset_offset = 96;
static constexpr dart::compiler::target::word Field_guarded_list_length_offset =
- 48;
-static constexpr dart::compiler::target::word Field_is_nullable_offset = 82;
-static constexpr dart::compiler::target::word Field_kind_bits_offset = 90;
+ 56;
+static constexpr dart::compiler::target::word Field_is_nullable_offset = 90;
+static constexpr dart::compiler::target::word Field_kind_bits_offset = 98;
static constexpr dart::compiler::target::word Function_code_offset = 88;
static constexpr dart::compiler::target::word Function_entry_point_offset[] = {
8, 16};
@@ -2576,9 +2600,9 @@
static constexpr dart::compiler::target::word
Thread_AllocateArray_entry_point_offset = 720;
static constexpr dart::compiler::target::word Thread_active_exception_offset =
- 1384;
-static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
1392;
+static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
+ 1400;
static constexpr dart::compiler::target::word
Thread_array_write_barrier_code_offset = 240;
static constexpr dart::compiler::target::word
@@ -2615,7 +2639,7 @@
Thread_call_to_runtime_entry_point_offset = 512;
static constexpr dart::compiler::target::word
Thread_call_to_runtime_stub_offset = 280;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1456;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1464;
static constexpr dart::compiler::target::word
Thread_dispatch_table_array_offset = 96;
static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
@@ -2633,7 +2657,7 @@
static constexpr dart::compiler::target::word
Thread_enter_safepoint_stub_offset = 472;
static constexpr dart::compiler::target::word Thread_execution_state_offset =
- 1424;
+ 1432;
static constexpr dart::compiler::target::word
Thread_exit_safepoint_stub_offset = 480;
static constexpr dart::compiler::target::word
@@ -2653,7 +2677,7 @@
static constexpr dart::compiler::target::word
Thread_float_zerow_address_offset = 712;
static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
- 1400;
+ 1408;
static constexpr dart::compiler::target::word
Thread_interpret_call_entry_point_offset = 648;
static constexpr dart::compiler::target::word
@@ -2694,11 +2718,11 @@
static constexpr dart::compiler::target::word Thread_object_null_offset = 208;
static constexpr dart::compiler::target::word
Thread_predefined_symbols_address_offset = 656;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1408;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1416;
static constexpr dart::compiler::target::word
- Thread_saved_shadow_call_stack_offset = 1416;
+ Thread_saved_shadow_call_stack_offset = 1424;
static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
- 1432;
+ 1440;
static constexpr dart::compiler::target::word
Thread_slow_type_test_stub_offset = 456;
static constexpr dart::compiler::target::word
@@ -2732,7 +2756,7 @@
static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
80;
static constexpr dart::compiler::target::word Thread_callback_code_offset =
- 1440;
+ 1448;
static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
16;
static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
@@ -2768,8 +2792,8 @@
8, 24, 16, 32};
static constexpr dart::compiler::target::word
Thread_write_barrier_wrappers_thread_offset[] = {
- 1296, 1304, 1312, 1320, -1, -1, 1328, 1336,
- 1344, 1352, 1360, -1, 1368, 1376, -1, -1};
+ 1304, 1312, 1320, 1328, -1, -1, 1336, 1344,
+ 1352, 1360, 1368, -1, 1376, 1384, -1, -1};
static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
static constexpr dart::compiler::target::word Array_InstanceSize = 24;
static constexpr dart::compiler::target::word Array_header_size = 24;
@@ -2800,7 +2824,7 @@
24;
static constexpr dart::compiler::target::word FfiTrampolineData_InstanceSize =
48;
-static constexpr dart::compiler::target::word Field_InstanceSize = 112;
+static constexpr dart::compiler::target::word Field_InstanceSize = 104;
static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
static constexpr dart::compiler::target::word Function_InstanceSize = 152;
@@ -2961,13 +2985,17 @@
ExternalTwoByteString_external_data_offset = 12;
static constexpr dart::compiler::target::word Float32x4_value_offset = 8;
static constexpr dart::compiler::target::word Float64x2_value_offset = 8;
-static constexpr dart::compiler::target::word Field_guarded_cid_offset = 44;
static constexpr dart::compiler::target::word
- Field_guarded_list_length_in_object_offset_offset = 52;
+ Field_initializer_function_offset = 16;
+static constexpr dart::compiler::target::word
+ Field_host_offset_or_field_id_offset = 20;
+static constexpr dart::compiler::target::word Field_guarded_cid_offset = 48;
+static constexpr dart::compiler::target::word
+ Field_guarded_list_length_in_object_offset_offset = 56;
static constexpr dart::compiler::target::word Field_guarded_list_length_offset =
- 24;
-static constexpr dart::compiler::target::word Field_is_nullable_offset = 46;
-static constexpr dart::compiler::target::word Field_kind_bits_offset = 54;
+ 28;
+static constexpr dart::compiler::target::word Field_is_nullable_offset = 50;
+static constexpr dart::compiler::target::word Field_kind_bits_offset = 58;
static constexpr dart::compiler::target::word Function_code_offset = 44;
static constexpr dart::compiler::target::word Function_entry_point_offset[] = {
4, 8};
@@ -3049,9 +3077,9 @@
static constexpr dart::compiler::target::word
Thread_AllocateArray_entry_point_offset = 368;
static constexpr dart::compiler::target::word Thread_active_exception_offset =
- 656;
-static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
660;
+static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
+ 664;
static constexpr dart::compiler::target::word
Thread_array_write_barrier_code_offset = 128;
static constexpr dart::compiler::target::word
@@ -3088,7 +3116,7 @@
Thread_call_to_runtime_entry_point_offset = 264;
static constexpr dart::compiler::target::word
Thread_call_to_runtime_stub_offset = 148;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 692;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 696;
static constexpr dart::compiler::target::word
Thread_dispatch_table_array_offset = 48;
static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
@@ -3106,7 +3134,7 @@
static constexpr dart::compiler::target::word
Thread_enter_safepoint_stub_offset = 244;
static constexpr dart::compiler::target::word Thread_execution_state_offset =
- 676;
+ 680;
static constexpr dart::compiler::target::word
Thread_exit_safepoint_stub_offset = 248;
static constexpr dart::compiler::target::word
@@ -3126,7 +3154,7 @@
static constexpr dart::compiler::target::word
Thread_float_zerow_address_offset = 364;
static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
- 664;
+ 668;
static constexpr dart::compiler::target::word
Thread_interpret_call_entry_point_offset = 332;
static constexpr dart::compiler::target::word
@@ -3167,11 +3195,11 @@
static constexpr dart::compiler::target::word Thread_object_null_offset = 112;
static constexpr dart::compiler::target::word
Thread_predefined_symbols_address_offset = 336;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 668;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 672;
static constexpr dart::compiler::target::word
- Thread_saved_shadow_call_stack_offset = 672;
+ Thread_saved_shadow_call_stack_offset = 676;
static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
- 680;
+ 684;
static constexpr dart::compiler::target::word
Thread_slow_type_test_stub_offset = 236;
static constexpr dart::compiler::target::word
@@ -3204,7 +3232,7 @@
Thread_write_barrier_entry_point_offset = 256;
static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
40;
-static constexpr dart::compiler::target::word Thread_callback_code_offset = 684;
+static constexpr dart::compiler::target::word Thread_callback_code_offset = 688;
static constexpr dart::compiler::target::word TimelineStream_enabled_offset = 8;
static constexpr dart::compiler::target::word TwoByteString_data_offset = 12;
static constexpr dart::compiler::target::word Type_arguments_offset = 16;
@@ -3429,13 +3457,17 @@
ExternalTwoByteString_external_data_offset = 16;
static constexpr dart::compiler::target::word Float32x4_value_offset = 8;
static constexpr dart::compiler::target::word Float64x2_value_offset = 8;
-static constexpr dart::compiler::target::word Field_guarded_cid_offset = 80;
static constexpr dart::compiler::target::word
- Field_guarded_list_length_in_object_offset_offset = 88;
+ Field_initializer_function_offset = 32;
+static constexpr dart::compiler::target::word
+ Field_host_offset_or_field_id_offset = 40;
+static constexpr dart::compiler::target::word Field_guarded_cid_offset = 88;
+static constexpr dart::compiler::target::word
+ Field_guarded_list_length_in_object_offset_offset = 96;
static constexpr dart::compiler::target::word Field_guarded_list_length_offset =
- 48;
-static constexpr dart::compiler::target::word Field_is_nullable_offset = 82;
-static constexpr dart::compiler::target::word Field_kind_bits_offset = 90;
+ 56;
+static constexpr dart::compiler::target::word Field_is_nullable_offset = 90;
+static constexpr dart::compiler::target::word Field_kind_bits_offset = 98;
static constexpr dart::compiler::target::word Function_code_offset = 88;
static constexpr dart::compiler::target::word Function_entry_point_offset[] = {
8, 16};
@@ -3518,9 +3550,9 @@
static constexpr dart::compiler::target::word
Thread_AllocateArray_entry_point_offset = 720;
static constexpr dart::compiler::target::word Thread_active_exception_offset =
- 1456;
-static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
1464;
+static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
+ 1472;
static constexpr dart::compiler::target::word
Thread_array_write_barrier_code_offset = 240;
static constexpr dart::compiler::target::word
@@ -3557,7 +3589,7 @@
Thread_call_to_runtime_entry_point_offset = 512;
static constexpr dart::compiler::target::word
Thread_call_to_runtime_stub_offset = 280;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1528;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1536;
static constexpr dart::compiler::target::word
Thread_dispatch_table_array_offset = 96;
static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
@@ -3575,7 +3607,7 @@
static constexpr dart::compiler::target::word
Thread_enter_safepoint_stub_offset = 472;
static constexpr dart::compiler::target::word Thread_execution_state_offset =
- 1496;
+ 1504;
static constexpr dart::compiler::target::word
Thread_exit_safepoint_stub_offset = 480;
static constexpr dart::compiler::target::word
@@ -3595,7 +3627,7 @@
static constexpr dart::compiler::target::word
Thread_float_zerow_address_offset = 712;
static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
- 1472;
+ 1480;
static constexpr dart::compiler::target::word
Thread_interpret_call_entry_point_offset = 648;
static constexpr dart::compiler::target::word
@@ -3636,11 +3668,11 @@
static constexpr dart::compiler::target::word Thread_object_null_offset = 208;
static constexpr dart::compiler::target::word
Thread_predefined_symbols_address_offset = 656;
-static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1480;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1488;
static constexpr dart::compiler::target::word
- Thread_saved_shadow_call_stack_offset = 1488;
+ Thread_saved_shadow_call_stack_offset = 1496;
static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
- 1504;
+ 1512;
static constexpr dart::compiler::target::word
Thread_slow_type_test_stub_offset = 456;
static constexpr dart::compiler::target::word
@@ -3674,7 +3706,7 @@
static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
80;
static constexpr dart::compiler::target::word Thread_callback_code_offset =
- 1512;
+ 1520;
static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
16;
static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
@@ -3710,9 +3742,9 @@
8, 24, 16, 32};
static constexpr dart::compiler::target::word
Thread_write_barrier_wrappers_thread_offset[] = {
- 1296, 1304, 1312, 1320, 1328, 1336, 1344, 1352, 1360, 1368, 1376,
- 1384, 1392, 1400, 1408, -1, -1, -1, -1, 1416, 1424, -1,
- -1, 1432, 1440, 1448, -1, -1, -1, -1, -1, -1};
+ 1304, 1312, 1320, 1328, 1336, 1344, 1352, 1360, 1368, 1376, 1384,
+ 1392, 1400, 1408, 1416, -1, -1, -1, -1, 1424, 1432, -1,
+ -1, 1440, 1448, 1456, -1, -1, -1, -1, -1, -1};
static constexpr dart::compiler::target::word ApiError_InstanceSize = 16;
static constexpr dart::compiler::target::word Array_InstanceSize = 24;
static constexpr dart::compiler::target::word Array_header_size = 24;
@@ -3743,7 +3775,7 @@
24;
static constexpr dart::compiler::target::word FfiTrampolineData_InstanceSize =
48;
-static constexpr dart::compiler::target::word Field_InstanceSize = 112;
+static constexpr dart::compiler::target::word Field_InstanceSize = 104;
static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
static constexpr dart::compiler::target::word Function_InstanceSize = 152;
@@ -3916,6 +3948,10 @@
AOT_ExternalTwoByteString_external_data_offset = 12;
static constexpr dart::compiler::target::word AOT_Float32x4_value_offset = 8;
static constexpr dart::compiler::target::word AOT_Float64x2_value_offset = 8;
+static constexpr dart::compiler::target::word
+ AOT_Field_initializer_function_offset = 16;
+static constexpr dart::compiler::target::word
+ AOT_Field_host_offset_or_field_id_offset = 20;
static constexpr dart::compiler::target::word AOT_Function_code_offset = 44;
static constexpr dart::compiler::target::word
AOT_Function_entry_point_offset[] = {4, 8};
@@ -4009,9 +4045,9 @@
static constexpr dart::compiler::target::word
AOT_Thread_AllocateArray_entry_point_offset = 368;
static constexpr dart::compiler::target::word
- AOT_Thread_active_exception_offset = 688;
+ AOT_Thread_active_exception_offset = 692;
static constexpr dart::compiler::target::word
- AOT_Thread_active_stacktrace_offset = 692;
+ AOT_Thread_active_stacktrace_offset = 696;
static constexpr dart::compiler::target::word
AOT_Thread_array_write_barrier_code_offset = 128;
static constexpr dart::compiler::target::word
@@ -4050,7 +4086,7 @@
static constexpr dart::compiler::target::word
AOT_Thread_call_to_runtime_stub_offset = 148;
static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
- 724;
+ 728;
static constexpr dart::compiler::target::word
AOT_Thread_dispatch_table_array_offset = 48;
static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
@@ -4069,7 +4105,7 @@
static constexpr dart::compiler::target::word
AOT_Thread_enter_safepoint_stub_offset = 244;
static constexpr dart::compiler::target::word
- AOT_Thread_execution_state_offset = 708;
+ AOT_Thread_execution_state_offset = 712;
static constexpr dart::compiler::target::word
AOT_Thread_exit_safepoint_stub_offset = 248;
static constexpr dart::compiler::target::word
@@ -4089,7 +4125,7 @@
static constexpr dart::compiler::target::word
AOT_Thread_float_zerow_address_offset = 364;
static constexpr dart::compiler::target::word
- AOT_Thread_global_object_pool_offset = 696;
+ AOT_Thread_global_object_pool_offset = 700;
static constexpr dart::compiler::target::word
AOT_Thread_interpret_call_entry_point_offset = 332;
static constexpr dart::compiler::target::word
@@ -4131,11 +4167,11 @@
112;
static constexpr dart::compiler::target::word
AOT_Thread_predefined_symbols_address_offset = 336;
-static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = 700;
+static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = 704;
static constexpr dart::compiler::target::word
- AOT_Thread_saved_shadow_call_stack_offset = 704;
+ AOT_Thread_saved_shadow_call_stack_offset = 708;
static constexpr dart::compiler::target::word
- AOT_Thread_safepoint_state_offset = 712;
+ AOT_Thread_safepoint_state_offset = 716;
static constexpr dart::compiler::target::word
AOT_Thread_slow_type_test_stub_offset = 236;
static constexpr dart::compiler::target::word
@@ -4171,7 +4207,7 @@
static constexpr dart::compiler::target::word
AOT_Thread_write_barrier_mask_offset = 40;
static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
- 716;
+ 720;
static constexpr dart::compiler::target::word
AOT_TimelineStream_enabled_offset = 8;
static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
@@ -4216,7 +4252,7 @@
4, 12, 8, 16};
static constexpr dart::compiler::target::word
AOT_Thread_write_barrier_wrappers_thread_offset[] = {
- 656, 660, 664, 668, 672, -1, 676, -1, 680, 684, -1, -1, -1, -1, -1, -1};
+ 660, 664, 668, 672, 676, -1, 680, -1, 684, 688, -1, -1, -1, -1, -1, -1};
static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 8;
static constexpr dart::compiler::target::word AOT_Array_InstanceSize = 12;
static constexpr dart::compiler::target::word AOT_Array_header_size = 12;
@@ -4435,6 +4471,10 @@
AOT_ExternalTwoByteString_external_data_offset = 16;
static constexpr dart::compiler::target::word AOT_Float32x4_value_offset = 8;
static constexpr dart::compiler::target::word AOT_Float64x2_value_offset = 8;
+static constexpr dart::compiler::target::word
+ AOT_Field_initializer_function_offset = 32;
+static constexpr dart::compiler::target::word
+ AOT_Field_host_offset_or_field_id_offset = 40;
static constexpr dart::compiler::target::word AOT_Function_code_offset = 88;
static constexpr dart::compiler::target::word
AOT_Function_entry_point_offset[] = {8, 16};
@@ -4528,9 +4568,9 @@
static constexpr dart::compiler::target::word
AOT_Thread_AllocateArray_entry_point_offset = 720;
static constexpr dart::compiler::target::word
- AOT_Thread_active_exception_offset = 1384;
+ AOT_Thread_active_exception_offset = 1392;
static constexpr dart::compiler::target::word
- AOT_Thread_active_stacktrace_offset = 1392;
+ AOT_Thread_active_stacktrace_offset = 1400;
static constexpr dart::compiler::target::word
AOT_Thread_array_write_barrier_code_offset = 240;
static constexpr dart::compiler::target::word
@@ -4569,7 +4609,7 @@
static constexpr dart::compiler::target::word
AOT_Thread_call_to_runtime_stub_offset = 280;
static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
- 1456;
+ 1464;
static constexpr dart::compiler::target::word
AOT_Thread_dispatch_table_array_offset = 96;
static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
@@ -4588,7 +4628,7 @@
static constexpr dart::compiler::target::word
AOT_Thread_enter_safepoint_stub_offset = 472;
static constexpr dart::compiler::target::word
- AOT_Thread_execution_state_offset = 1424;
+ AOT_Thread_execution_state_offset = 1432;
static constexpr dart::compiler::target::word
AOT_Thread_exit_safepoint_stub_offset = 480;
static constexpr dart::compiler::target::word
@@ -4608,7 +4648,7 @@
static constexpr dart::compiler::target::word
AOT_Thread_float_zerow_address_offset = 712;
static constexpr dart::compiler::target::word
- AOT_Thread_global_object_pool_offset = 1400;
+ AOT_Thread_global_object_pool_offset = 1408;
static constexpr dart::compiler::target::word
AOT_Thread_interpret_call_entry_point_offset = 648;
static constexpr dart::compiler::target::word
@@ -4651,11 +4691,11 @@
static constexpr dart::compiler::target::word
AOT_Thread_predefined_symbols_address_offset = 656;
static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
- 1408;
+ 1416;
static constexpr dart::compiler::target::word
- AOT_Thread_saved_shadow_call_stack_offset = 1416;
+ AOT_Thread_saved_shadow_call_stack_offset = 1424;
static constexpr dart::compiler::target::word
- AOT_Thread_safepoint_state_offset = 1432;
+ AOT_Thread_safepoint_state_offset = 1440;
static constexpr dart::compiler::target::word
AOT_Thread_slow_type_test_stub_offset = 456;
static constexpr dart::compiler::target::word
@@ -4691,7 +4731,7 @@
static constexpr dart::compiler::target::word
AOT_Thread_write_barrier_mask_offset = 80;
static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
- 1440;
+ 1448;
static constexpr dart::compiler::target::word
AOT_TimelineStream_enabled_offset = 16;
static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
@@ -4736,8 +4776,8 @@
8, 24, 16, 32};
static constexpr dart::compiler::target::word
AOT_Thread_write_barrier_wrappers_thread_offset[] = {
- 1296, 1304, 1312, 1320, -1, -1, 1328, 1336,
- 1344, 1352, 1360, -1, 1368, 1376, -1, -1};
+ 1304, 1312, 1320, 1328, -1, -1, 1336, 1344,
+ 1352, 1360, 1368, -1, 1376, 1384, -1, -1};
static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_Array_InstanceSize = 24;
static constexpr dart::compiler::target::word AOT_Array_header_size = 24;
@@ -4960,6 +5000,10 @@
AOT_ExternalTwoByteString_external_data_offset = 16;
static constexpr dart::compiler::target::word AOT_Float32x4_value_offset = 8;
static constexpr dart::compiler::target::word AOT_Float64x2_value_offset = 8;
+static constexpr dart::compiler::target::word
+ AOT_Field_initializer_function_offset = 32;
+static constexpr dart::compiler::target::word
+ AOT_Field_host_offset_or_field_id_offset = 40;
static constexpr dart::compiler::target::word AOT_Function_code_offset = 88;
static constexpr dart::compiler::target::word
AOT_Function_entry_point_offset[] = {8, 16};
@@ -5053,9 +5097,9 @@
static constexpr dart::compiler::target::word
AOT_Thread_AllocateArray_entry_point_offset = 720;
static constexpr dart::compiler::target::word
- AOT_Thread_active_exception_offset = 1456;
+ AOT_Thread_active_exception_offset = 1464;
static constexpr dart::compiler::target::word
- AOT_Thread_active_stacktrace_offset = 1464;
+ AOT_Thread_active_stacktrace_offset = 1472;
static constexpr dart::compiler::target::word
AOT_Thread_array_write_barrier_code_offset = 240;
static constexpr dart::compiler::target::word
@@ -5094,7 +5138,7 @@
static constexpr dart::compiler::target::word
AOT_Thread_call_to_runtime_stub_offset = 280;
static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
- 1528;
+ 1536;
static constexpr dart::compiler::target::word
AOT_Thread_dispatch_table_array_offset = 96;
static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
@@ -5113,7 +5157,7 @@
static constexpr dart::compiler::target::word
AOT_Thread_enter_safepoint_stub_offset = 472;
static constexpr dart::compiler::target::word
- AOT_Thread_execution_state_offset = 1496;
+ AOT_Thread_execution_state_offset = 1504;
static constexpr dart::compiler::target::word
AOT_Thread_exit_safepoint_stub_offset = 480;
static constexpr dart::compiler::target::word
@@ -5133,7 +5177,7 @@
static constexpr dart::compiler::target::word
AOT_Thread_float_zerow_address_offset = 712;
static constexpr dart::compiler::target::word
- AOT_Thread_global_object_pool_offset = 1472;
+ AOT_Thread_global_object_pool_offset = 1480;
static constexpr dart::compiler::target::word
AOT_Thread_interpret_call_entry_point_offset = 648;
static constexpr dart::compiler::target::word
@@ -5176,11 +5220,11 @@
static constexpr dart::compiler::target::word
AOT_Thread_predefined_symbols_address_offset = 656;
static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
- 1480;
+ 1488;
static constexpr dart::compiler::target::word
- AOT_Thread_saved_shadow_call_stack_offset = 1488;
+ AOT_Thread_saved_shadow_call_stack_offset = 1496;
static constexpr dart::compiler::target::word
- AOT_Thread_safepoint_state_offset = 1504;
+ AOT_Thread_safepoint_state_offset = 1512;
static constexpr dart::compiler::target::word
AOT_Thread_slow_type_test_stub_offset = 456;
static constexpr dart::compiler::target::word
@@ -5216,7 +5260,7 @@
static constexpr dart::compiler::target::word
AOT_Thread_write_barrier_mask_offset = 80;
static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
- 1512;
+ 1520;
static constexpr dart::compiler::target::word
AOT_TimelineStream_enabled_offset = 16;
static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
@@ -5261,9 +5305,9 @@
8, 24, 16, 32};
static constexpr dart::compiler::target::word
AOT_Thread_write_barrier_wrappers_thread_offset[] = {
- 1296, 1304, 1312, 1320, 1328, 1336, 1344, 1352, 1360, 1368, 1376,
- 1384, 1392, 1400, 1408, -1, -1, -1, -1, 1416, 1424, -1,
- -1, 1432, 1440, 1448, -1, -1, -1, -1, -1, -1};
+ 1304, 1312, 1320, 1328, 1336, 1344, 1352, 1360, 1368, 1376, 1384,
+ 1392, 1400, 1408, 1416, -1, -1, -1, -1, 1424, 1432, -1,
+ -1, 1440, 1448, 1456, -1, -1, -1, -1, -1, -1};
static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_Array_InstanceSize = 24;
static constexpr dart::compiler::target::word AOT_Array_header_size = 24;
@@ -5483,6 +5527,10 @@
AOT_ExternalTwoByteString_external_data_offset = 12;
static constexpr dart::compiler::target::word AOT_Float32x4_value_offset = 8;
static constexpr dart::compiler::target::word AOT_Float64x2_value_offset = 8;
+static constexpr dart::compiler::target::word
+ AOT_Field_initializer_function_offset = 16;
+static constexpr dart::compiler::target::word
+ AOT_Field_host_offset_or_field_id_offset = 20;
static constexpr dart::compiler::target::word AOT_Function_code_offset = 44;
static constexpr dart::compiler::target::word
AOT_Function_entry_point_offset[] = {4, 8};
@@ -5574,9 +5622,9 @@
static constexpr dart::compiler::target::word
AOT_Thread_AllocateArray_entry_point_offset = 368;
static constexpr dart::compiler::target::word
- AOT_Thread_active_exception_offset = 688;
+ AOT_Thread_active_exception_offset = 692;
static constexpr dart::compiler::target::word
- AOT_Thread_active_stacktrace_offset = 692;
+ AOT_Thread_active_stacktrace_offset = 696;
static constexpr dart::compiler::target::word
AOT_Thread_array_write_barrier_code_offset = 128;
static constexpr dart::compiler::target::word
@@ -5615,7 +5663,7 @@
static constexpr dart::compiler::target::word
AOT_Thread_call_to_runtime_stub_offset = 148;
static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
- 724;
+ 728;
static constexpr dart::compiler::target::word
AOT_Thread_dispatch_table_array_offset = 48;
static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
@@ -5634,7 +5682,7 @@
static constexpr dart::compiler::target::word
AOT_Thread_enter_safepoint_stub_offset = 244;
static constexpr dart::compiler::target::word
- AOT_Thread_execution_state_offset = 708;
+ AOT_Thread_execution_state_offset = 712;
static constexpr dart::compiler::target::word
AOT_Thread_exit_safepoint_stub_offset = 248;
static constexpr dart::compiler::target::word
@@ -5654,7 +5702,7 @@
static constexpr dart::compiler::target::word
AOT_Thread_float_zerow_address_offset = 364;
static constexpr dart::compiler::target::word
- AOT_Thread_global_object_pool_offset = 696;
+ AOT_Thread_global_object_pool_offset = 700;
static constexpr dart::compiler::target::word
AOT_Thread_interpret_call_entry_point_offset = 332;
static constexpr dart::compiler::target::word
@@ -5696,11 +5744,11 @@
112;
static constexpr dart::compiler::target::word
AOT_Thread_predefined_symbols_address_offset = 336;
-static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = 700;
+static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = 704;
static constexpr dart::compiler::target::word
- AOT_Thread_saved_shadow_call_stack_offset = 704;
+ AOT_Thread_saved_shadow_call_stack_offset = 708;
static constexpr dart::compiler::target::word
- AOT_Thread_safepoint_state_offset = 712;
+ AOT_Thread_safepoint_state_offset = 716;
static constexpr dart::compiler::target::word
AOT_Thread_slow_type_test_stub_offset = 236;
static constexpr dart::compiler::target::word
@@ -5736,7 +5784,7 @@
static constexpr dart::compiler::target::word
AOT_Thread_write_barrier_mask_offset = 40;
static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
- 716;
+ 720;
static constexpr dart::compiler::target::word
AOT_TimelineStream_enabled_offset = 8;
static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
@@ -5778,7 +5826,7 @@
4, 12, 8, 16};
static constexpr dart::compiler::target::word
AOT_Thread_write_barrier_wrappers_thread_offset[] = {
- 656, 660, 664, 668, 672, -1, 676, -1, 680, 684, -1, -1, -1, -1, -1, -1};
+ 660, 664, 668, 672, 676, -1, 680, -1, 684, 688, -1, -1, -1, -1, -1, -1};
static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 8;
static constexpr dart::compiler::target::word AOT_Array_InstanceSize = 12;
static constexpr dart::compiler::target::word AOT_Array_header_size = 12;
@@ -5995,6 +6043,10 @@
AOT_ExternalTwoByteString_external_data_offset = 16;
static constexpr dart::compiler::target::word AOT_Float32x4_value_offset = 8;
static constexpr dart::compiler::target::word AOT_Float64x2_value_offset = 8;
+static constexpr dart::compiler::target::word
+ AOT_Field_initializer_function_offset = 32;
+static constexpr dart::compiler::target::word
+ AOT_Field_host_offset_or_field_id_offset = 40;
static constexpr dart::compiler::target::word AOT_Function_code_offset = 88;
static constexpr dart::compiler::target::word
AOT_Function_entry_point_offset[] = {8, 16};
@@ -6086,9 +6138,9 @@
static constexpr dart::compiler::target::word
AOT_Thread_AllocateArray_entry_point_offset = 720;
static constexpr dart::compiler::target::word
- AOT_Thread_active_exception_offset = 1384;
+ AOT_Thread_active_exception_offset = 1392;
static constexpr dart::compiler::target::word
- AOT_Thread_active_stacktrace_offset = 1392;
+ AOT_Thread_active_stacktrace_offset = 1400;
static constexpr dart::compiler::target::word
AOT_Thread_array_write_barrier_code_offset = 240;
static constexpr dart::compiler::target::word
@@ -6127,7 +6179,7 @@
static constexpr dart::compiler::target::word
AOT_Thread_call_to_runtime_stub_offset = 280;
static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
- 1456;
+ 1464;
static constexpr dart::compiler::target::word
AOT_Thread_dispatch_table_array_offset = 96;
static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
@@ -6146,7 +6198,7 @@
static constexpr dart::compiler::target::word
AOT_Thread_enter_safepoint_stub_offset = 472;
static constexpr dart::compiler::target::word
- AOT_Thread_execution_state_offset = 1424;
+ AOT_Thread_execution_state_offset = 1432;
static constexpr dart::compiler::target::word
AOT_Thread_exit_safepoint_stub_offset = 480;
static constexpr dart::compiler::target::word
@@ -6166,7 +6218,7 @@
static constexpr dart::compiler::target::word
AOT_Thread_float_zerow_address_offset = 712;
static constexpr dart::compiler::target::word
- AOT_Thread_global_object_pool_offset = 1400;
+ AOT_Thread_global_object_pool_offset = 1408;
static constexpr dart::compiler::target::word
AOT_Thread_interpret_call_entry_point_offset = 648;
static constexpr dart::compiler::target::word
@@ -6209,11 +6261,11 @@
static constexpr dart::compiler::target::word
AOT_Thread_predefined_symbols_address_offset = 656;
static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
- 1408;
+ 1416;
static constexpr dart::compiler::target::word
- AOT_Thread_saved_shadow_call_stack_offset = 1416;
+ AOT_Thread_saved_shadow_call_stack_offset = 1424;
static constexpr dart::compiler::target::word
- AOT_Thread_safepoint_state_offset = 1432;
+ AOT_Thread_safepoint_state_offset = 1440;
static constexpr dart::compiler::target::word
AOT_Thread_slow_type_test_stub_offset = 456;
static constexpr dart::compiler::target::word
@@ -6249,7 +6301,7 @@
static constexpr dart::compiler::target::word
AOT_Thread_write_barrier_mask_offset = 80;
static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
- 1440;
+ 1448;
static constexpr dart::compiler::target::word
AOT_TimelineStream_enabled_offset = 16;
static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
@@ -6291,8 +6343,8 @@
8, 24, 16, 32};
static constexpr dart::compiler::target::word
AOT_Thread_write_barrier_wrappers_thread_offset[] = {
- 1296, 1304, 1312, 1320, -1, -1, 1328, 1336,
- 1344, 1352, 1360, -1, 1368, 1376, -1, -1};
+ 1304, 1312, 1320, 1328, -1, -1, 1336, 1344,
+ 1352, 1360, 1368, -1, 1376, 1384, -1, -1};
static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_Array_InstanceSize = 24;
static constexpr dart::compiler::target::word AOT_Array_header_size = 24;
@@ -6513,6 +6565,10 @@
AOT_ExternalTwoByteString_external_data_offset = 16;
static constexpr dart::compiler::target::word AOT_Float32x4_value_offset = 8;
static constexpr dart::compiler::target::word AOT_Float64x2_value_offset = 8;
+static constexpr dart::compiler::target::word
+ AOT_Field_initializer_function_offset = 32;
+static constexpr dart::compiler::target::word
+ AOT_Field_host_offset_or_field_id_offset = 40;
static constexpr dart::compiler::target::word AOT_Function_code_offset = 88;
static constexpr dart::compiler::target::word
AOT_Function_entry_point_offset[] = {8, 16};
@@ -6604,9 +6660,9 @@
static constexpr dart::compiler::target::word
AOT_Thread_AllocateArray_entry_point_offset = 720;
static constexpr dart::compiler::target::word
- AOT_Thread_active_exception_offset = 1456;
+ AOT_Thread_active_exception_offset = 1464;
static constexpr dart::compiler::target::word
- AOT_Thread_active_stacktrace_offset = 1464;
+ AOT_Thread_active_stacktrace_offset = 1472;
static constexpr dart::compiler::target::word
AOT_Thread_array_write_barrier_code_offset = 240;
static constexpr dart::compiler::target::word
@@ -6645,7 +6701,7 @@
static constexpr dart::compiler::target::word
AOT_Thread_call_to_runtime_stub_offset = 280;
static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
- 1528;
+ 1536;
static constexpr dart::compiler::target::word
AOT_Thread_dispatch_table_array_offset = 96;
static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
@@ -6664,7 +6720,7 @@
static constexpr dart::compiler::target::word
AOT_Thread_enter_safepoint_stub_offset = 472;
static constexpr dart::compiler::target::word
- AOT_Thread_execution_state_offset = 1496;
+ AOT_Thread_execution_state_offset = 1504;
static constexpr dart::compiler::target::word
AOT_Thread_exit_safepoint_stub_offset = 480;
static constexpr dart::compiler::target::word
@@ -6684,7 +6740,7 @@
static constexpr dart::compiler::target::word
AOT_Thread_float_zerow_address_offset = 712;
static constexpr dart::compiler::target::word
- AOT_Thread_global_object_pool_offset = 1472;
+ AOT_Thread_global_object_pool_offset = 1480;
static constexpr dart::compiler::target::word
AOT_Thread_interpret_call_entry_point_offset = 648;
static constexpr dart::compiler::target::word
@@ -6727,11 +6783,11 @@
static constexpr dart::compiler::target::word
AOT_Thread_predefined_symbols_address_offset = 656;
static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset =
- 1480;
+ 1488;
static constexpr dart::compiler::target::word
- AOT_Thread_saved_shadow_call_stack_offset = 1488;
+ AOT_Thread_saved_shadow_call_stack_offset = 1496;
static constexpr dart::compiler::target::word
- AOT_Thread_safepoint_state_offset = 1504;
+ AOT_Thread_safepoint_state_offset = 1512;
static constexpr dart::compiler::target::word
AOT_Thread_slow_type_test_stub_offset = 456;
static constexpr dart::compiler::target::word
@@ -6767,7 +6823,7 @@
static constexpr dart::compiler::target::word
AOT_Thread_write_barrier_mask_offset = 80;
static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset =
- 1512;
+ 1520;
static constexpr dart::compiler::target::word
AOT_TimelineStream_enabled_offset = 16;
static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
@@ -6809,9 +6865,9 @@
8, 24, 16, 32};
static constexpr dart::compiler::target::word
AOT_Thread_write_barrier_wrappers_thread_offset[] = {
- 1296, 1304, 1312, 1320, 1328, 1336, 1344, 1352, 1360, 1368, 1376,
- 1384, 1392, 1400, 1408, -1, -1, -1, -1, 1416, 1424, -1,
- -1, 1432, 1440, 1448, -1, -1, -1, -1, -1, -1};
+ 1304, 1312, 1320, 1328, 1336, 1344, 1352, 1360, 1368, 1376, 1384,
+ 1392, 1400, 1408, 1416, -1, -1, -1, -1, 1424, 1432, -1,
+ -1, 1440, 1448, 1456, -1, -1, -1, -1, -1, -1};
static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_Array_InstanceSize = 24;
static constexpr dart::compiler::target::word AOT_Array_header_size = 24;
diff --git a/runtime/vm/compiler/runtime_offsets_list.h b/runtime/vm/compiler/runtime_offsets_list.h
index 5c9b5e4..5371356 100644
--- a/runtime/vm/compiler/runtime_offsets_list.h
+++ b/runtime/vm/compiler/runtime_offsets_list.h
@@ -83,6 +83,8 @@
FIELD(ExternalTwoByteString, external_data_offset) \
FIELD(Float32x4, value_offset) \
FIELD(Float64x2, value_offset) \
+ FIELD(Field, initializer_function_offset) \
+ FIELD(Field, host_offset_or_field_id_offset) \
PRECOMP_NO_CHECK(FIELD(Field, guarded_cid_offset)) \
PRECOMP_NO_CHECK(FIELD(Field, guarded_list_length_in_object_offset_offset)) \
PRECOMP_NO_CHECK(FIELD(Field, guarded_list_length_offset)) \
diff --git a/runtime/vm/compiler/stub_code_compiler.cc b/runtime/vm/compiler/stub_code_compiler.cc
index 7d91690..27a2839 100644
--- a/runtime/vm/compiler/stub_code_compiler.cc
+++ b/runtime/vm/compiler/stub_code_compiler.cc
@@ -38,6 +38,72 @@
__ Ret();
}
+void StubCodeCompiler::GenerateInitLateInstanceFieldStub(Assembler* assembler,
+ bool is_final) {
+ __ EnterStubFrame();
+ // Save for later.
+ __ PushRegisterPair(InitInstanceFieldABI::kInstanceReg,
+ InitInstanceFieldABI::kFieldReg);
+
+ // Call initializer function.
+ __ PushRegister(InitInstanceFieldABI::kInstanceReg);
+
+ const Register kFunctionReg = InitLateInstanceFieldInternalRegs::kFunctionReg;
+ const Register kInitializerResultReg =
+ InitLateInstanceFieldInternalRegs::kInitializerResultReg;
+ const Register kInstanceReg = InitLateInstanceFieldInternalRegs::kInstanceReg;
+ const Register kFieldReg = InitLateInstanceFieldInternalRegs::kFieldReg;
+ const Register kAddressReg = InitLateInstanceFieldInternalRegs::kAddressReg;
+ const Register kScratchReg = InitLateInstanceFieldInternalRegs::kScratchReg;
+
+ __ LoadField(kFunctionReg,
+ FieldAddress(InitInstanceFieldABI::kFieldReg,
+ target::Field::initializer_function_offset()));
+ if (!FLAG_precompiled_mode || !FLAG_use_bare_instructions) {
+ __ LoadField(CODE_REG,
+ FieldAddress(kFunctionReg, target::Function::code_offset()));
+ }
+ __ Call(FieldAddress(kFunctionReg, target::Function::entry_point_offset()));
+ __ Drop(1); // Drop argument.
+
+ __ PopRegisterPair(kInstanceReg, kFieldReg);
+ __ LoadField(
+ kScratchReg,
+ FieldAddress(kFieldReg, target::Field::host_offset_or_field_id_offset()));
+ __ LoadFieldAddressForRegOffset(kAddressReg, kInstanceReg, kScratchReg);
+
+ Label throw_exception;
+ if (is_final) {
+ __ LoadMemoryValue(kScratchReg, kAddressReg, 0);
+ __ CompareObject(kScratchReg, SentinelObject());
+ __ BranchIf(NOT_EQUAL, &throw_exception);
+ }
+
+ __ StoreIntoObject(kInstanceReg, Address(kAddressReg, 0),
+ kInitializerResultReg);
+
+ __ LeaveStubFrame();
+ __ Ret();
+
+ if (is_final) {
+ __ Bind(&throw_exception);
+ __ PushObject(NullObject()); // Make room for (unused) result.
+ __ PushRegister(kFieldReg);
+ __ CallRuntime(kLateInitializationErrorRuntimeEntry,
+ /*argument_count=*/1);
+ __ Breakpoint();
+ }
+}
+
+void StubCodeCompiler::GenerateInitLateInstanceFieldStub(Assembler* assembler) {
+ GenerateInitLateInstanceFieldStub(assembler, /*is_final=*/false);
+}
+
+void StubCodeCompiler::GenerateInitLateFinalInstanceFieldStub(
+ Assembler* assembler) {
+ GenerateInitLateInstanceFieldStub(assembler, /*is_final=*/true);
+}
+
void StubCodeCompiler::GenerateThrowStub(Assembler* assembler) {
__ EnterStubFrame();
__ PushObject(NullObject()); // Make room for (unused) result.
diff --git a/runtime/vm/compiler/stub_code_compiler.h b/runtime/vm/compiler/stub_code_compiler.h
index 6193417..6c4f4a3 100644
--- a/runtime/vm/compiler/stub_code_compiler.h
+++ b/runtime/vm/compiler/stub_code_compiler.h
@@ -125,6 +125,12 @@
static void GenerateJITCallbackTrampolines(Assembler* assembler,
intptr_t next_callback_id);
+
+ private:
+ // Common function for generating InitLateInstanceField and
+ // InitLateFinalInstanceField stubs.
+ static void GenerateInitLateInstanceFieldStub(Assembler* assembler,
+ bool is_final);
};
} // namespace compiler
diff --git a/runtime/vm/constants_arm.h b/runtime/vm/constants_arm.h
index b068e7f..e58b312 100644
--- a/runtime/vm/constants_arm.h
+++ b/runtime/vm/constants_arm.h
@@ -356,6 +356,16 @@
static const Register kFieldReg = R1;
};
+// Registers used inside the implementation of InitLateInstanceFieldStub.
+struct InitLateInstanceFieldInternalRegs {
+ static const Register kFunctionReg = R0;
+ static const Register kInitializerResultReg = R0;
+ static const Register kInstanceReg = R1;
+ static const Register kFieldReg = R2;
+ static const Register kAddressReg = R3;
+ static const Register kScratchReg = R4;
+};
+
// ABI for ThrowStub.
struct ThrowABI {
static const Register kExceptionReg = R0;
diff --git a/runtime/vm/constants_arm64.h b/runtime/vm/constants_arm64.h
index 9929f0d..c4f8f4b 100644
--- a/runtime/vm/constants_arm64.h
+++ b/runtime/vm/constants_arm64.h
@@ -188,6 +188,16 @@
static const Register kFieldReg = R1;
};
+// Registers used inside the implementation of InitLateInstanceFieldStub.
+struct InitLateInstanceFieldInternalRegs {
+ static const Register kFunctionReg = R0;
+ static const Register kInitializerResultReg = R0;
+ static const Register kInstanceReg = R1;
+ static const Register kFieldReg = R2;
+ static const Register kAddressReg = R3;
+ static const Register kScratchReg = R4;
+};
+
// ABI for ThrowStub.
struct ThrowABI {
static const Register kExceptionReg = R0;
diff --git a/runtime/vm/constants_ia32.h b/runtime/vm/constants_ia32.h
index 2f7d689..cfa49ee 100644
--- a/runtime/vm/constants_ia32.h
+++ b/runtime/vm/constants_ia32.h
@@ -127,6 +127,16 @@
static const Register kFieldReg = EBX;
};
+// Registers used inside the implementation of InitLateInstanceFieldStub.
+struct InitLateInstanceFieldInternalRegs {
+ static const Register kFunctionReg = EAX;
+ static const Register kInitializerResultReg = EAX;
+ static const Register kInstanceReg = EBX;
+ static const Register kFieldReg = EDX;
+ static const Register kAddressReg = ECX;
+ static const Register kScratchReg = EDI;
+};
+
// ABI for ThrowStub.
struct ThrowABI {
static const Register kExceptionReg = EAX;
diff --git a/runtime/vm/constants_x64.h b/runtime/vm/constants_x64.h
index f4030c9..7f99877 100644
--- a/runtime/vm/constants_x64.h
+++ b/runtime/vm/constants_x64.h
@@ -169,6 +169,16 @@
static const Register kFieldReg = RBX;
};
+// Registers used inside the implementation of InitLateInstanceFieldStub.
+struct InitLateInstanceFieldInternalRegs {
+ static const Register kFunctionReg = RAX;
+ static const Register kInitializerResultReg = RAX;
+ static const Register kInstanceReg = RBX;
+ static const Register kFieldReg = RDX;
+ static const Register kAddressReg = RCX;
+ static const Register kScratchReg = RSI;
+};
+
// ABI for ThrowStub.
struct ThrowABI {
static const Register kExceptionReg = RAX;
diff --git a/runtime/vm/interpreter.cc b/runtime/vm/interpreter.cc
index c5b27e3..c31b7da 100644
--- a/runtime/vm/interpreter.cc
+++ b/runtime/vm/interpreter.cc
@@ -2326,7 +2326,8 @@
BYTECODE(InitLateField, D);
FieldPtr field = RAW_CAST(Field, LOAD_CONSTANT(rD + 1));
InstancePtr instance = static_cast<InstancePtr>(SP[0]);
- intptr_t offset_in_words = field->ptr()->host_offset_or_field_id_;
+ intptr_t offset_in_words =
+ Smi::Value(field->ptr()->host_offset_or_field_id_);
instance->ptr()->StorePointer(
reinterpret_cast<ObjectPtr*>(instance->ptr()) + offset_in_words,
@@ -2355,7 +2356,7 @@
BYTECODE(StoreStaticTOS, D);
FieldPtr field = static_cast<FieldPtr>(LOAD_CONSTANT(rD));
InstancePtr value = static_cast<InstancePtr>(*SP--);
- intptr_t field_id = field->ptr()->host_offset_or_field_id_;
+ intptr_t field_id = Smi::Value(field->ptr()->host_offset_or_field_id_);
thread->field_table_values()[field_id] = value;
DISPATCH();
}
@@ -2363,7 +2364,7 @@
{
BYTECODE(LoadStatic, D);
FieldPtr field = static_cast<FieldPtr>(LOAD_CONSTANT(rD));
- intptr_t field_id = field->ptr()->host_offset_or_field_id_;
+ intptr_t field_id = Smi::Value(field->ptr()->host_offset_or_field_id_);
InstancePtr value = thread->field_table_values()[field_id];
ASSERT((value != Object::sentinel().raw()) &&
(value != Object::transition_sentinel().raw()));
@@ -2376,7 +2377,8 @@
FieldPtr field = RAW_CAST(Field, LOAD_CONSTANT(rD + 1));
InstancePtr instance = static_cast<InstancePtr>(SP[-1]);
ObjectPtr value = static_cast<ObjectPtr>(SP[0]);
- intptr_t offset_in_words = field->ptr()->host_offset_or_field_id_;
+ intptr_t offset_in_words =
+ Smi::Value(field->ptr()->host_offset_or_field_id_);
if (InterpreterHelpers::FieldNeedsGuardUpdate(field, value)) {
SP[1] = 0; // Unused result of runtime call.
@@ -3158,7 +3160,8 @@
// Field object is cached in function's data_.
FieldPtr field = static_cast<FieldPtr>(function->ptr()->data_);
- intptr_t offset_in_words = field->ptr()->host_offset_or_field_id_;
+ intptr_t offset_in_words =
+ Smi::Value(field->ptr()->host_offset_or_field_id_);
const intptr_t kArgc = 1;
InstancePtr instance =
@@ -3178,7 +3181,7 @@
function = FrameFunction(FP);
instance = static_cast<InstancePtr>(SP[2]);
field = static_cast<FieldPtr>(SP[3]);
- offset_in_words = field->ptr()->host_offset_or_field_id_;
+ offset_in_words = Smi::Value(field->ptr()->host_offset_or_field_id_);
value = reinterpret_cast<InstancePtr*>(instance->ptr())[offset_in_words];
}
@@ -3239,7 +3242,8 @@
// Field object is cached in function's data_.
FieldPtr field = static_cast<FieldPtr>(function->ptr()->data_);
- intptr_t offset_in_words = field->ptr()->host_offset_or_field_id_;
+ intptr_t offset_in_words =
+ Smi::Value(field->ptr()->host_offset_or_field_id_);
const intptr_t kArgc = 2;
InstancePtr instance =
static_cast<InstancePtr>(FrameArguments(FP, kArgc)[0]);
@@ -3318,7 +3322,7 @@
// Field object is cached in function's data_.
FieldPtr field = static_cast<FieldPtr>(function->ptr()->data_);
- intptr_t field_id = field->ptr()->host_offset_or_field_id_;
+ intptr_t field_id = Smi::Value(field->ptr()->host_offset_or_field_id_);
InstancePtr value = thread->field_table_values()[field_id];
if (value == Object::sentinel().raw() ||
value == Object::transition_sentinel().raw()) {
@@ -3332,7 +3336,7 @@
function = FrameFunction(FP);
field = static_cast<FieldPtr>(function->ptr()->data_);
// The field is initialized by the runtime call, but not returned.
- intptr_t field_id = field->ptr()->host_offset_or_field_id_;
+ intptr_t field_id = Smi::Value(field->ptr()->host_offset_or_field_id_);
value = thread->field_table_values()[field_id];
}
diff --git a/runtime/vm/isolate_reload.cc b/runtime/vm/isolate_reload.cc
index faaa2ac..6c995de 100644
--- a/runtime/vm/isolate_reload.cc
+++ b/runtime/vm/isolate_reload.cc
@@ -688,6 +688,8 @@
kernel::KernelLoader::FindModifiedLibraries(
kernel_program.get(), first_isolate_, modified_libs_, force_reload,
&skip_reload, p_num_received_classes, p_num_received_procedures);
+ modified_libs_transitive_ = new (Z) BitVector(Z, num_old_libs_);
+ BuildModifiedLibrariesClosure(modified_libs_);
ASSERT(num_saved_libs_ == -1);
num_saved_libs_ = 0;
@@ -746,6 +748,7 @@
});
// Renumbering the libraries has invalidated this.
modified_libs_ = nullptr;
+ modified_libs_transitive_ = nullptr;
if (FLAG_gc_during_reload) {
// We use kLowMemory to force the GC to compact, which is more likely to
@@ -960,6 +963,108 @@
return success;
}
+/// Copied in from https://dart-review.googlesource.com/c/sdk/+/77722.
+static void PropagateLibraryModified(
+ const ZoneGrowableArray<ZoneGrowableArray<intptr_t>*>* imported_by,
+ intptr_t lib_index,
+ BitVector* modified_libs) {
+ ZoneGrowableArray<intptr_t>* dep_libs = (*imported_by)[lib_index];
+ for (intptr_t i = 0; i < dep_libs->length(); i++) {
+ intptr_t dep_lib_index = (*dep_libs)[i];
+ if (!modified_libs->Contains(dep_lib_index)) {
+ modified_libs->Add(dep_lib_index);
+ PropagateLibraryModified(imported_by, dep_lib_index, modified_libs);
+ }
+ }
+}
+
+/// Copied in from https://dart-review.googlesource.com/c/sdk/+/77722.
+void IsolateGroupReloadContext::BuildModifiedLibrariesClosure(
+ BitVector* modified_libs) {
+ const GrowableObjectArray& libs =
+ GrowableObjectArray::Handle(first_isolate_->object_store()->libraries());
+ Library& lib = Library::Handle();
+ intptr_t num_libs = libs.Length();
+
+ // Construct the imported-by graph.
+ ZoneGrowableArray<ZoneGrowableArray<intptr_t>*>* imported_by = new (zone_)
+ ZoneGrowableArray<ZoneGrowableArray<intptr_t>*>(zone_, num_libs);
+ imported_by->SetLength(num_libs);
+ for (intptr_t i = 0; i < num_libs; i++) {
+ (*imported_by)[i] = new (zone_) ZoneGrowableArray<intptr_t>(zone_, 0);
+ }
+ Array& ports = Array::Handle();
+ Namespace& ns = Namespace::Handle();
+ Library& target = Library::Handle();
+ String& target_url = String::Handle();
+
+ for (intptr_t lib_idx = 0; lib_idx < num_libs; lib_idx++) {
+ lib ^= libs.At(lib_idx);
+ ASSERT(lib_idx == lib.index());
+ if (lib.is_dart_scheme()) {
+ // We don't care about imports among dart scheme libraries.
+ continue;
+ }
+
+ // Add imports to the import-by graph.
+ ports = lib.imports();
+ for (intptr_t import_idx = 0; import_idx < ports.Length(); import_idx++) {
+ ns ^= ports.At(import_idx);
+ if (!ns.IsNull()) {
+ target = ns.library();
+ target_url = target.url();
+ if (!target_url.StartsWith(Symbols::DartExtensionScheme())) {
+ (*imported_by)[target.index()]->Add(lib.index());
+ }
+ }
+ }
+
+ // Add exports to the import-by graph.
+ ports = lib.exports();
+ for (intptr_t export_idx = 0; export_idx < ports.Length(); export_idx++) {
+ ns ^= ports.At(export_idx);
+ if (!ns.IsNull()) {
+ target = ns.library();
+ (*imported_by)[target.index()]->Add(lib.index());
+ }
+ }
+
+ // Add prefixed imports to the import-by graph.
+ DictionaryIterator entries(lib);
+ Object& entry = Object::Handle();
+ LibraryPrefix& prefix = LibraryPrefix::Handle();
+ while (entries.HasNext()) {
+ entry = entries.GetNext();
+ if (entry.IsLibraryPrefix()) {
+ prefix ^= entry.raw();
+ ports = prefix.imports();
+ for (intptr_t import_idx = 0; import_idx < ports.Length();
+ import_idx++) {
+ ns ^= ports.At(import_idx);
+ if (!ns.IsNull()) {
+ target = ns.library();
+ (*imported_by)[target.index()]->Add(lib.index());
+ }
+ }
+ }
+ }
+ }
+
+ for (intptr_t lib_idx = 0; lib_idx < num_libs; lib_idx++) {
+ lib ^= libs.At(lib_idx);
+ if (lib.is_dart_scheme() || modified_libs_transitive_->Contains(lib_idx)) {
+ // We don't consider dart scheme libraries during reload. If
+ // the modified libs set already contains this library, then we
+ // have already visited it.
+ continue;
+ }
+ if (modified_libs->Contains(lib_idx)) {
+ modified_libs_transitive_->Add(lib_idx);
+ PropagateLibraryModified(imported_by, lib_idx, modified_libs_transitive_);
+ }
+ }
+}
+
void IsolateGroupReloadContext::GetRootLibUrl(const char* root_script_url) {
const auto& old_root_lib =
Library::Handle(first_isolate_->object_store()->root_library());
@@ -1381,6 +1486,9 @@
Library& lib = Library::Handle();
UnorderedHashSet<LibraryMapTraits> old_libraries_set(
old_libraries_set_storage_);
+
+ group_reload_context_->saved_libs_transitive_updated_ = new (Z)
+ BitVector(Z, group_reload_context_->modified_libs_transitive_->length());
for (intptr_t i = 0; i < libs.Length(); i++) {
lib ^= libs.At(i);
if (group_reload_context_->modified_libs_->Contains(i)) {
@@ -1390,6 +1498,11 @@
// We are preserving this library across the reload, assign its new index
lib.set_index(new_libs.Length());
new_libs.Add(lib, Heap::kOld);
+
+ if (group_reload_context_->modified_libs_transitive_->Contains(i)) {
+ // Remember the new index.
+ group_reload_context_->saved_libs_transitive_updated_->Add(lib.index());
+ }
}
// Add old library to old libraries set.
bool already_present = old_libraries_set.Insert(lib);
@@ -1569,7 +1682,10 @@
for (intptr_t i = 0; i < libs.Length(); i++) {
lib = Library::RawCast(libs.At(i));
// Mark the library dirty if it comes after the libraries we saved.
- library_infos_[i].dirty = i >= group_reload_context_->num_saved_libs_;
+ library_infos_[i].dirty =
+ i >= group_reload_context_->num_saved_libs_ ||
+ group_reload_context_->saved_libs_transitive_updated_->Contains(
+ lib.index());
}
}
}
@@ -2086,11 +2202,8 @@
Thread* thread = Thread::Current();
Isolate* isolate = thread->isolate();
bool null_safety = isolate->null_safety();
+ HANDLESCOPE(thread);
for (intptr_t i = 0; i < instances.length(); i++) {
- // This handle scope does run very frequently, but is a net-win by
- // preventing us from spending too much time in malloc for new handle
- // blocks.
- HANDLESCOPE(thread);
CheckInstance(null_safety, *instances[i]);
}
}
diff --git a/runtime/vm/isolate_reload.h b/runtime/vm/isolate_reload.h
index 492b5bf..2295441 100644
--- a/runtime/vm/isolate_reload.h
+++ b/runtime/vm/isolate_reload.h
@@ -211,6 +211,7 @@
const char* packages_url,
const uint8_t** kernel_buffer,
intptr_t* kernel_buffer_size);
+ void BuildModifiedLibrariesClosure(BitVector* modified_libs);
void FindModifiedSources(bool force_reload,
Dart_SourceFile** modified_sources,
intptr_t* count,
@@ -272,6 +273,14 @@
// A bit vector indicating which of the original libraries were modified.
BitVector* modified_libs_ = nullptr;
+ // A bit vector indicating which of the original libraries were modified,
+ // or where a transitive dependency was modified.
+ BitVector* modified_libs_transitive_ = nullptr;
+
+ // A bit vector indicating which of the saved libraries that transitively
+ // depend on a modified libary.
+ BitVector* saved_libs_transitive_updated_ = nullptr;
+
String& root_lib_url_;
ObjectPtr* from() { return reinterpret_cast<ObjectPtr*>(&root_url_prefix_); }
StringPtr root_url_prefix_;
diff --git a/runtime/vm/kernel.cc b/runtime/vm/kernel.cc
index 1b98d07..d6663e3 100644
--- a/runtime/vm/kernel.cc
+++ b/runtime/vm/kernel.cc
@@ -757,7 +757,8 @@
for (intptr_t i = 0, n = type_params.Length(); i < n; ++i) {
type_param ^= type_params.TypeAt(i);
bound = type_param.bound();
- if (!bound.IsTopType() && !type_param.IsGenericCovariantImpl()) {
+ if (!bound.IsTopTypeForSubtyping() &&
+ !type_param.IsGenericCovariantImpl()) {
return true;
}
}
@@ -771,7 +772,7 @@
auto& type = AbstractType::Handle(zone);
for (intptr_t i = function.NumImplicitParameters(); i < num_params; ++i) {
type = function.ParameterTypeAt(i);
- if (!type.IsTopTypeForAssignability() &&
+ if (!type.IsTopTypeForSubtyping() &&
!is_generic_covariant_impl.Contains(i) && !is_covariant.Contains(i)) {
return true;
}
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index ec90971..73a21be 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -2870,11 +2870,10 @@
}
ArrayPtr Class::OffsetToFieldMap(bool original_classes) const {
- Array& array = Array::Handle(raw_ptr()->offset_in_words_to_field_);
- if (array.IsNull()) {
+ if (raw_ptr()->offset_in_words_to_field_ == Array::null()) {
ASSERT(is_finalized());
const intptr_t length = raw_ptr()->host_instance_size_in_words_;
- array = Array::New(length, Heap::kOld);
+ const Array& array = Array::Handle(Array::New(length, Heap::kOld));
Class& cls = Class::Handle(this->raw());
Array& fields = Array::Handle();
Field& f = Field::Handle();
@@ -2890,7 +2889,7 @@
}
StorePointer(&raw_ptr()->offset_in_words_to_field_, array.raw());
}
- return array.raw();
+ return raw_ptr()->offset_in_words_to_field_;
}
bool Class::HasInstanceFields() const {
@@ -4989,7 +4988,7 @@
const AbstractType& other_type_arg =
AbstractType::Handle(zone, other_type_arguments.TypeAtNullSafe(0));
// Check if S1 is a top type.
- if (other_type_arg.IsTopType()) {
+ if (other_type_arg.IsTopTypeForSubtyping()) {
return true;
}
// Check T0 <: Future<S1> when T0 is Future<S0>.
@@ -5030,19 +5029,20 @@
// Since we do not truncate the type argument vector of a subclass (see
// below), we only check a subvector of the proper length.
// Check for covariance.
- if (other_type_arguments.IsNull() ||
- other_type_arguments.IsTopTypes(from_index, num_type_params)) {
+ if (other_type_arguments.IsNull()) {
return true;
}
- if (type_arguments.IsNull() ||
- type_arguments.IsRaw(from_index, num_type_params)) {
- // Other type can't be more specific than this one because for that
- // it would have to have all dynamic type arguments which is checked
- // above.
- return false;
+ AbstractType& type = AbstractType::Handle(zone);
+ AbstractType& other_type = AbstractType::Handle(zone);
+ for (intptr_t i = 0; i < num_type_params; ++i) {
+ type = type_arguments.TypeAtNullSafe(from_index + i);
+ other_type = other_type_arguments.TypeAt(from_index + i);
+ ASSERT(!type.IsNull() && !other_type.IsNull());
+ if (!type.IsSubtypeOf(other_type, space)) {
+ return false;
+ }
}
- return type_arguments.IsSubtypeOf(other_type_arguments, from_index,
- num_type_params, space);
+ return true;
}
// Check for 'direct super type' specified in the implements clause
// and check for transitivity at the same time.
@@ -5891,38 +5891,6 @@
return true;
}
-bool TypeArguments::IsTopTypes(intptr_t from_index, intptr_t len) const {
- ASSERT(Length() >= (from_index + len));
- AbstractType& type = AbstractType::Handle();
- for (intptr_t i = 0; i < len; i++) {
- type = TypeAt(from_index + i);
- if (type.IsNull() || !type.IsTopType()) {
- return false;
- }
- }
- return true;
-}
-
-bool TypeArguments::IsSubtypeOf(const TypeArguments& other,
- intptr_t from_index,
- intptr_t len,
- Heap::Space space) const {
- ASSERT(Length() >= (from_index + len));
- ASSERT(!other.IsNull());
- ASSERT(other.Length() >= (from_index + len));
- AbstractType& type = AbstractType::Handle();
- AbstractType& other_type = AbstractType::Handle();
- for (intptr_t i = 0; i < len; i++) {
- type = TypeAt(from_index + i);
- other_type = other.TypeAt(from_index + i);
- if (type.IsNull() || other_type.IsNull() ||
- !type.IsSubtypeOf(other_type, space)) {
- return false;
- }
- }
- return true;
-}
-
bool TypeArguments::HasInstantiations() const {
const Array& prior_instantiations = Array::Handle(instantiations());
ASSERT(prior_instantiations.Length() > 0); // Always at least a sentinel.
@@ -7991,7 +7959,7 @@
Heap::Space space) const {
const AbstractType& param_type =
AbstractType::Handle(ParameterTypeAt(parameter_position));
- if (param_type.IsTopType()) {
+ if (param_type.IsTopTypeForSubtyping()) {
return true;
}
const AbstractType& other_param_type =
@@ -8074,7 +8042,7 @@
const AbstractType& other_res_type =
AbstractType::Handle(zone, other.result_type());
// 'void Function()' is a subtype of 'Object Function()'.
- if (!other_res_type.IsTopType()) {
+ if (!other_res_type.IsTopTypeForSubtyping()) {
const AbstractType& res_type = AbstractType::Handle(zone, result_type());
if (!res_type.IsSubtypeOf(other_res_type, space)) {
return false;
@@ -17863,7 +17831,9 @@
ASSERT(other.IsFinalized());
ASSERT(!other.IsTypeRef()); // Must be dereferenced at compile time.
if (other.IsNullable()) {
- // The type will remain nullable after instantiation.
+ // This case includes top types (void, dynamic, Object?).
+ // The uninstantiated nullable type will remain nullable after
+ // instantiation.
return true;
}
if (other.IsFutureOrType()) {
@@ -17883,7 +17853,7 @@
return Instance::NullIsInstanceOf(type, Object::null_type_arguments(),
Object::null_type_arguments());
}
- return other.IsLegacy() && (other.IsTopType() || other.IsNeverType());
+ return other.IsLegacy() && (other.IsObjectType() || other.IsNeverType());
}
bool Instance::NullIsAssignableTo(const AbstractType& other) {
@@ -17914,10 +17884,9 @@
const TypeArguments& other_function_type_arguments) const {
ASSERT(other.IsFinalized());
ASSERT(!other.IsTypeRef()); // Must be dereferenced at compile time.
- // Note that Object::sentinel() has Null class, but !IsNull().
ASSERT(raw() != Object::sentinel().raw());
// Instance may not have runtimeType dynamic, void, or Never.
- if (other.IsTopType()) {
+ if (other.IsTopTypeForSubtyping()) {
return true;
}
Thread* thread = Thread::Current();
@@ -17941,12 +17910,12 @@
if (instantiated_other.IsTypeRef()) {
instantiated_other = TypeRef::Cast(instantiated_other).type();
}
- if (instantiated_other.IsTopType() ||
+ if (instantiated_other.IsTopTypeForSubtyping() ||
instantiated_other.IsDartFunctionType()) {
return true;
}
}
- if (IsFutureOrInstanceOf(zone, instantiated_other)) {
+ if (RuntimeTypeIsSubtypeOfFutureOr(zone, instantiated_other)) {
return true;
}
if (!instantiated_other.IsFunctionType()) {
@@ -17981,7 +17950,7 @@
if (instantiated_other.IsTypeRef()) {
instantiated_other = TypeRef::Cast(instantiated_other).type();
}
- if (instantiated_other.IsTopType()) {
+ if (instantiated_other.IsTopTypeForSubtyping()) {
return true;
}
}
@@ -17993,7 +17962,7 @@
if (instantiated_other.IsNullType()) {
return true;
}
- if (IsFutureOrInstanceOf(zone, instantiated_other)) {
+ if (RuntimeTypeIsSubtypeOfFutureOr(zone, instantiated_other)) {
return true;
}
return !instantiated_other.IsNonNullable();
@@ -18004,14 +17973,14 @@
instantiated_other, Heap::kOld);
}
-bool Instance::IsFutureOrInstanceOf(Zone* zone,
- const AbstractType& other) const {
+bool Instance::RuntimeTypeIsSubtypeOfFutureOr(Zone* zone,
+ const AbstractType& other) const {
if (other.IsFutureOrType()) {
const TypeArguments& other_type_arguments =
TypeArguments::Handle(zone, other.arguments());
const AbstractType& other_type_arg =
AbstractType::Handle(zone, other_type_arguments.TypeAtNullSafe(0));
- if (other_type_arg.IsTopType()) {
+ if (other_type_arg.IsTopTypeForSubtyping()) {
return true;
}
if (Class::Handle(zone, clazz()).IsFutureClass()) {
@@ -18687,8 +18656,7 @@
return type_class_id() == kNeverCid;
}
-// Caution: IsTopType() does not return true for non-nullable Object.
-bool AbstractType::IsTopType() const {
+bool AbstractType::IsTopTypeForInstanceOf() const {
const classid_t cid = type_class_id();
if (cid == kDynamicCid || cid == kVoidCid) {
return true;
@@ -18698,12 +18666,12 @@
}
if (cid == kFutureOrCid) {
// FutureOr<T> where T is a top type behaves as a top type.
- return AbstractType::Handle(UnwrapFutureOr()).IsTopType();
+ return AbstractType::Handle(UnwrapFutureOr()).IsTopTypeForInstanceOf();
}
return false;
}
-bool AbstractType::IsTopTypeForAssignability() const {
+bool AbstractType::IsTopTypeForSubtyping() const {
const classid_t cid = type_class_id();
if (cid == kDynamicCid || cid == kVoidCid) {
return true;
@@ -18711,11 +18679,11 @@
if (cid == kInstanceCid) { // Object type.
// NNBD weak mode uses LEGACY_SUBTYPE for assignability / 'as' tests,
// and non-nullable Object is a top type according to LEGACY_SUBTYPE.
- return !Isolate::Current()->null_safety() || !IsNonNullable();
+ return !IsNonNullable() || !Isolate::Current()->null_safety();
}
if (cid == kFutureOrCid) {
// FutureOr<T> where T is a top type behaves as a top type.
- return AbstractType::Handle(UnwrapFutureOr()).IsTopTypeForAssignability();
+ return AbstractType::Handle(UnwrapFutureOr()).IsTopTypeForSubtyping();
}
return false;
}
@@ -18801,7 +18769,7 @@
return true;
}
// Right top type.
- if (other.IsTopType()) {
+ if (other.IsTopTypeForSubtyping()) {
return true;
}
// Left bottom type.
@@ -18914,7 +18882,7 @@
TypeArguments::Handle(zone, other.arguments());
const AbstractType& other_type_arg =
AbstractType::Handle(zone, other_type_arguments.TypeAtNullSafe(0));
- if (other_type_arg.IsTopType()) {
+ if (other_type_arg.IsTopTypeForSubtyping()) {
return true;
}
// Retry the IsSubtypeOf check after unwrapping type arg of FutureOr.
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 39f112a..82779b4 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -3958,14 +3958,18 @@
intptr_t target_offset_in_bytes) const;
inline intptr_t HostOffset() const;
+ static intptr_t host_offset_or_field_id_offset() {
+ return OFFSET_OF(FieldLayout, host_offset_or_field_id_);
+ }
inline intptr_t TargetOffset() const;
+ static inline intptr_t TargetOffsetOf(FieldPtr field);
inline InstancePtr StaticValue() const;
void SetStaticValue(const Instance& value,
bool save_initial_value = false) const;
- intptr_t field_id() const { return raw_ptr()->host_offset_or_field_id_; }
+ inline intptr_t field_id() const;
inline void set_field_id(intptr_t field_id) const;
#ifndef DART_PRECOMPILED_RUNTIME
@@ -4074,14 +4078,6 @@
return OFFSET_OF(FieldLayout, static_type_exactness_state_);
}
- static inline intptr_t TargetOffsetOf(const FieldPtr field) {
-#if !defined(DART_PRECOMPILED_RUNTIME)
- return field->ptr()->target_offset_;
-#else
- return field->ptr()->host_offset_or_field_id_;
-#endif // !defined(DART_PRECOMPILED_RUNTIME)
- }
-
// Return class id that any non-null value read from this field is guaranteed
// to have or kDynamicCid if such class id is not known.
// Stores to this field must update this information hence the name.
@@ -4229,6 +4225,9 @@
}
void SetInitializerFunction(const Function& initializer) const;
bool HasInitializerFunction() const;
+ static intptr_t initializer_function_offset() {
+ return OFFSET_OF(FieldLayout, initializer_function_);
+ }
// For static fields only. Constructs a closure that gets/sets the
// field value.
@@ -4684,13 +4683,13 @@
// Resolving native methods for script loaded in the library.
Dart_NativeEntryResolver native_entry_resolver() const {
- return raw_ptr()->native_entry_resolver_;
+ return LoadNonPointer(&raw_ptr()->native_entry_resolver_);
}
void set_native_entry_resolver(Dart_NativeEntryResolver value) const {
StoreNonPointer(&raw_ptr()->native_entry_resolver_, value);
}
Dart_NativeEntrySymbol native_entry_symbol_resolver() const {
- return raw_ptr()->native_entry_symbol_resolver_;
+ return LoadNonPointer(&raw_ptr()->native_entry_symbol_resolver_);
}
void set_native_entry_symbol_resolver(
Dart_NativeEntrySymbol native_symbol_resolver) const {
@@ -7120,12 +7119,6 @@
// [other] is a type parameter in NNBD strong mode).
static bool NullIsAssignableTo(const AbstractType& other);
- // Returns true if the type of this instance is a subtype of FutureOr<T>
- // specified by instantiated type 'other'.
- // Returns false if other type is not a FutureOr.
- bool IsFutureOrInstanceOf(Zone* zone,
- const AbstractType& other) const;
-
bool IsValidNativeIndex(int index) const {
return ((index >= 0) && (index < clazz()->ptr()->num_native_fields_));
}
@@ -7208,6 +7201,12 @@
const TypeArguments& other_instantiator_type_arguments,
const TypeArguments& other_function_type_arguments) const;
+ // Returns true if the type of this instance is a subtype of FutureOr<T>
+ // specified by instantiated type 'other'.
+ // Returns false if other type is not a FutureOr.
+ bool RuntimeTypeIsSubtypeOfFutureOr(Zone* zone,
+ const AbstractType& other) const;
+
// Return true if the null instance is an instance of other type.
static bool NullIsInstanceOf(
const AbstractType& other,
@@ -7390,18 +7389,6 @@
TypeArgumentsPtr ConcatenateTypeParameters(Zone* zone,
const TypeArguments& other) const;
- // Check if the subvector of length 'len' starting at 'from_index' of this
- // type argument vector consists solely of DynamicType, (nullable) ObjectType,
- // or VoidType.
- bool IsTopTypes(intptr_t from_index, intptr_t len) const;
-
- // Check the subtype relationship, considering only a subvector of length
- // 'len' starting at 'from_index'.
- bool IsSubtypeOf(const TypeArguments& other,
- intptr_t from_index,
- intptr_t len,
- Heap::Space space) const;
-
// Check if the vectors are equal (they may be null).
bool Equals(const TypeArguments& other) const {
return IsSubvectorEquivalent(other, 0, IsNull() ? 0 : Length(),
@@ -7729,15 +7716,18 @@
// Check if this type represents the 'Object' type.
bool IsObjectType() const { return type_class_id() == kInstanceCid; }
- // Check if this type represents a top type.
- bool IsTopType() const;
+ // Check if this type represents a top type for subtyping,
+ // assignability and 'as' type tests.
+ //
+ // Returns true if
+ // - any type is a subtype of this type;
+ // - any value can be assigned to a variable of this type;
+ // - 'as' type test always succeeds for this type.
+ bool IsTopTypeForSubtyping() const;
- // Check if this type represents a top type with respect to
- // assignability and 'as' type tests, e.g. returns true if any value can be
- // assigned to a variable of this type and 'as' type test always succeeds.
- // Guaranteed to return true for top types according to IsTopType(), but
- // may also return true for other types (non-nullable Object in weak mode).
- bool IsTopTypeForAssignability() const;
+ // Check if this type represents a top type for 'is' type tests.
+ // Returns true if 'is' type test always returns true for this type.
+ bool IsTopTypeForInstanceOf() const;
// Check if this type represents the 'bool' type.
bool IsBoolType() const { return type_class_id() == kBoolCid; }
@@ -10901,7 +10891,7 @@
intptr_t Field::HostOffset() const {
ASSERT(is_instance()); // Valid only for dart instance fields.
- return (raw_ptr()->host_offset_or_field_id_ * kWordSize);
+ return (Smi::Value(raw_ptr()->host_offset_or_field_id_) * kWordSize);
}
intptr_t Field::TargetOffset() const {
@@ -10913,12 +10903,20 @@
#endif // !defined(DART_PRECOMPILED_RUNTIME)
}
+inline intptr_t Field::TargetOffsetOf(const FieldPtr field) {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+ return field->ptr()->target_offset_;
+#else
+ return Smi::Value(field->ptr()->host_offset_or_field_id_);
+#endif // !defined(DART_PRECOMPILED_RUNTIME)
+}
+
void Field::SetOffset(intptr_t host_offset_in_bytes,
intptr_t target_offset_in_bytes) const {
ASSERT(is_instance()); // Valid only for dart instance fields.
ASSERT(kWordSize != 0);
- StoreNonPointer(&raw_ptr()->host_offset_or_field_id_,
- host_offset_in_bytes / kWordSize);
+ StoreSmi(&raw_ptr()->host_offset_or_field_id_,
+ Smi::New(host_offset_in_bytes / kWordSize));
#if !defined(DART_PRECOMPILED_RUNTIME)
ASSERT(compiler::target::kWordSize != 0);
StoreNonPointer(&raw_ptr()->target_offset_,
@@ -10931,13 +10929,17 @@
InstancePtr Field::StaticValue() const {
ASSERT(is_static()); // Valid only for static dart fields.
return Isolate::Current()->field_table()->At(
- raw_ptr()->host_offset_or_field_id_);
+ Smi::Value(raw_ptr()->host_offset_or_field_id_));
+}
+
+inline intptr_t Field::field_id() const {
+ return Smi::Value(raw_ptr()->host_offset_or_field_id_);
}
void Field::set_field_id(intptr_t field_id) const {
ASSERT(is_static());
ASSERT(Thread::Current()->IsMutatorThread());
- StoreNonPointer(&raw_ptr()->host_offset_or_field_id_, field_id);
+ StoreSmi(&raw_ptr()->host_offset_or_field_id_, Smi::New(field_id));
}
#ifndef DART_PRECOMPILED_RUNTIME
diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h
index dae1ce7..b28f776 100644
--- a/runtime/vm/object_store.h
+++ b/runtime/vm/object_store.h
@@ -198,6 +198,8 @@
RW(Code, instance_of_stub) \
RW(Code, init_static_field_stub) \
RW(Code, init_instance_field_stub) \
+ RW(Code, init_late_instance_field_stub) \
+ RW(Code, init_late_final_instance_field_stub) \
RW(Code, call_closure_no_such_method_stub) \
RW(Code, default_tts_stub) \
RW(Code, default_nullable_tts_stub) \
@@ -248,6 +250,8 @@
DO(assert_boolean_stub, AssertBoolean) \
DO(init_static_field_stub, InitStaticField) \
DO(init_instance_field_stub, InitInstanceField) \
+ DO(init_late_instance_field_stub, InitLateInstanceField) \
+ DO(init_late_final_instance_field_stub, InitLateFinalInstanceField) \
DO(instance_of_stub, InstanceOf)
#define ISOLATE_OBJECT_STORE_FIELD_LIST(R_, RW) \
diff --git a/runtime/vm/os_fuchsia.cc b/runtime/vm/os_fuchsia.cc
index 05985ab..1d3d4f6 100644
--- a/runtime/vm/os_fuchsia.cc
+++ b/runtime/vm/os_fuchsia.cc
@@ -12,38 +12,109 @@
#include <stdint.h>
#include <fuchsia/deprecatedtimezone/cpp/fidl.h>
+#include <lib/inspect/cpp/inspect.h>
+#include <lib/sys/cpp/component_context.h>
#include <lib/sys/cpp/service_directory.h>
+#include <lib/sys/inspect/cpp/component.h>
#include <zircon/process.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/object.h>
#include <zircon/types.h>
#include "platform/assert.h"
+#include "platform/utils.h"
#include "vm/zone.h"
-namespace dart {
+namespace {
// The data directory containing ICU timezone data files.
static constexpr char kICUTZDataDir[] = "/config/data/tzdata/icu/44/le";
+// The status codes for tzdata file open and read.
+enum class TZDataStatus {
+ OK = 0,
+ // The open call for the tzdata file did not succeed.
+ COULD_NOT_OPEN = -1,
+ // The close call (after tzdata was loaded) did not succeed.
+ COULD_NOT_CLOSE = -2,
+};
+
+// Adds a facility for introspecting timezone data errors. Allows insight into
+// the internal state of the VM even if error reporting facilities fail.
+class InspectMetrics {
+ public:
+ // Does not take ownership of inspector.
+ explicit InspectMetrics(inspect::Inspector* inspector)
+ : inspector_(inspector),
+ root_(inspector_->GetRoot()),
+ metrics_(root_.CreateChild("os")),
+ dst_status_(metrics_.CreateInt("dst_status", 0)),
+ tz_data_status_(metrics_.CreateInt("tz_data_status", 0)),
+ tz_data_close_status_(metrics_.CreateInt("tz_data_close_status", 0)) {}
+
+ // Sets the last status code for DST offset calls.
+ void SetDSTOffsetStatus(zx_status_t status) {
+ dst_status_.Set(static_cast<int32_t>(status));
+ }
+
+ // Sets the return value of call to InitializeTZData, and the status of the
+ // reported by close() on tzdata files.
+ void SetInitTzData(TZDataStatus value, int32_t status) {
+ tz_data_status_.Set(static_cast<int32_t>(value));
+ tz_data_close_status_.Set(status);
+ }
+
+ private:
+ // The inspector that all metrics are being reported into.
+ inspect::Inspector* inspector_;
+
+ // References inspector_ state.
+ inspect::Node& root_;
+
+ // The OS metrics node.
+ inspect::Node metrics_;
+
+ // The status of the last GetTimeZoneOffset call.
+ inspect::IntProperty dst_status_;
+
+ // The status of the initialization.
+ inspect::IntProperty tz_data_status_;
+
+ // The return code for the close() call for tzdata files.
+ inspect::IntProperty tz_data_close_status_;
+};
+
+// Initialized on OS:Init(), deinitialized on OS::Cleanup.
+std::unique_ptr<sys::ComponentInspector> component_inspector;
+std::unique_ptr<InspectMetrics> metrics;
+
// Initializes the source of timezone data if available. Timezone data file in
// Fuchsia is at a fixed directory path. Returns true on success.
bool InitializeTZData() {
+ ASSERT(metrics != nullptr);
// Try opening the path to check if present. No need to verify that it is a
// directory since ICU loading will return an error if the TZ data path is
// wrong.
int fd = openat(AT_FDCWD, kICUTZDataDir, O_RDONLY);
if (fd < 0) {
+ metrics->SetInitTzData(TZDataStatus::COULD_NOT_OPEN, fd);
return false;
}
// 0 == Not overwriting the env var if already set.
setenv("ICU_TIMEZONE_FILES_DIR", kICUTZDataDir, 0);
- if (!close(fd)) {
+ int32_t close_status = close(fd);
+ if (close_status != 0) {
+ metrics->SetInitTzData(TZDataStatus::COULD_NOT_CLOSE, close_status);
return false;
}
+ metrics->SetInitTzData(TZDataStatus::OK, 0);
return true;
}
+} // namespace
+
+namespace dart {
+
#ifndef PRODUCT
DEFINE_FLAG(bool,
@@ -74,6 +145,7 @@
int32_t* dst_offset) {
zx_status_t status = tz->GetTimezoneOffsetMinutes(seconds_since_epoch * 1000,
local_offset, dst_offset);
+ metrics->SetDSTOffsetStatus(status);
if (status != ZX_OK) {
return status;
}
@@ -263,12 +335,18 @@
}
void OS::Init() {
+ sys::ComponentContext* context = dart::ComponentContext();
+ component_inspector = std::make_unique<sys::ComponentInspector>(context);
+ metrics = std::make_unique<InspectMetrics>(component_inspector->inspector());
+
InitializeTZData();
- auto services = sys::ServiceDirectory::CreateFromNamespace();
- services->Connect(tz.NewRequest());
+ context->svc()->Connect(tz.NewRequest());
}
-void OS::Cleanup() {}
+void OS::Cleanup() {
+ metrics = nullptr;
+ component_inspector = nullptr;
+}
void OS::PrepareToAbort() {}
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 576d992..d9cccf9 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -1152,6 +1152,11 @@
// where this field is defined or original field.
AbstractTypePtr type_;
FunctionPtr initializer_function_; // Static initializer function.
+
+ // - for instance fields: offset in words to the value in the class instance.
+ // - for static fields: index into field_table.
+ SmiPtr host_offset_or_field_id_;
+
// When generating APPJIT snapshots after running the application it is
// necessary to save the initial value of static fields so that we can
// restore the value back to the original initial value.
@@ -1161,9 +1166,7 @@
ObjectPtr* to_snapshot(Snapshot::Kind kind) {
switch (kind) {
case Snapshot::kFull:
- return reinterpret_cast<ObjectPtr*>(&ptr()->guarded_list_length_);
case Snapshot::kFullJIT:
- return reinterpret_cast<ObjectPtr*>(&ptr()->dependent_code_);
case Snapshot::kFullAOT:
return reinterpret_cast<ObjectPtr*>(&ptr()->initializer_function_);
case Snapshot::kMessage:
@@ -1204,10 +1207,6 @@
uint16_t kind_bits_; // static, final, const, has initializer....
- // - for instance fields: offset in words to the value in the class instance.
- // - for static fields: index into field_table.
- intptr_t host_offset_or_field_id_;
-
#if !defined(DART_PRECOMPILED_RUNTIME)
// for instance fields, the offset in words in the target architecture
int32_t target_offset_;
diff --git a/runtime/vm/raw_object_fields.cc b/runtime/vm/raw_object_fields.cc
index c594b92..13c759b 100644
--- a/runtime/vm/raw_object_fields.cc
+++ b/runtime/vm/raw_object_fields.cc
@@ -56,6 +56,7 @@
F(Field, guarded_list_length_) \
F(Field, dependent_code_) \
F(Field, initializer_function_) \
+ F(Field, host_offset_or_field_id_) \
F(Script, url_) \
F(Script, resolved_url_) \
F(Script, compile_time_constants_) \
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index 46484be..ecd35ca 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -3166,6 +3166,11 @@
ThrowIfError(result);
}
+DEFINE_RUNTIME_ENTRY(LateInitializationError, 1) {
+ const Field& field = Field::CheckedHandle(zone, arguments.ArgAt(0));
+ Exceptions::ThrowLateInitializationError(String::Handle(field.name()));
+}
+
// Print the stop message.
DEFINE_LEAF_RUNTIME_ENTRY(void, PrintStopMessage, 1, const char* message) {
OS::PrintErr("Stop message: %s\n", message);
diff --git a/runtime/vm/runtime_entry_list.h b/runtime/vm/runtime_entry_list.h
index cf5ce11..de86028 100644
--- a/runtime/vm/runtime_entry_list.h
+++ b/runtime/vm/runtime_entry_list.h
@@ -53,6 +53,7 @@
V(UpdateFieldCid) \
V(InitInstanceField) \
V(InitStaticField) \
+ V(LateInitializationError) \
V(CompileFunction) \
V(CompileInterpretedFunction) \
V(SwitchableCallMiss)
diff --git a/runtime/vm/stub_code.cc b/runtime/vm/stub_code.cc
index bfe56d2..29906ec 100644
--- a/runtime/vm/stub_code.cc
+++ b/runtime/vm/stub_code.cc
@@ -322,7 +322,8 @@
auto object_store = Isolate::Current()->object_store();
#define DO(member, name) \
- if (entry_point == Code::EntryPointOf(object_store->member())) { \
+ if (object_store->member() != Code::null() && \
+ entry_point == Code::EntryPointOf(object_store->member())) { \
return "_iso_stub_" #name "Stub"; \
}
OBJECT_STORE_STUB_CODE_LIST(DO)
diff --git a/runtime/vm/stub_code_list.h b/runtime/vm/stub_code_list.h
index f6058e6..0c188c9 100644
--- a/runtime/vm/stub_code_list.h
+++ b/runtime/vm/stub_code_list.h
@@ -92,6 +92,8 @@
V(CallNativeThroughSafepoint) \
V(InitStaticField) \
V(InitInstanceField) \
+ V(InitLateInstanceField) \
+ V(InitLateFinalInstanceField) \
V(Throw) \
V(ReThrow) \
V(AssertBoolean) \
diff --git a/runtime/vm/type_testing_stubs.cc b/runtime/vm/type_testing_stubs.cc
index aac0b9c..b07969d 100644
--- a/runtime/vm/type_testing_stubs.cc
+++ b/runtime/vm/type_testing_stubs.cc
@@ -106,7 +106,7 @@
return Code::null();
}
- if (type.IsTopTypeForAssignability()) {
+ if (type.IsTopTypeForSubtyping()) {
return StubCode::TopTypeTypeTest().raw();
}
@@ -149,7 +149,7 @@
type, /*lazy_specialize=*/false);
}
- if (type.IsTopTypeForAssignability()) {
+ if (type.IsTopTypeForSubtyping()) {
return StubCode::TopTypeTypeTest().raw();
}
@@ -255,7 +255,7 @@
const Type& type,
const Class& type_class) {
// These are handled via the TopTypeTypeTestStub!
- ASSERT(!type.IsTopTypeForAssignability());
+ ASSERT(!type.IsTopTypeForSubtyping());
// Fast case for 'int'.
if (type.IsIntType()) {
@@ -420,7 +420,7 @@
const AbstractType& type_arg,
intptr_t type_param_value_offset_i,
compiler::Label* check_failed) {
- if (type_arg.IsTopType()) {
+ if (type_arg.IsTopTypeForSubtyping()) {
return;
}
diff --git a/sdk/lib/_http/http_parser.dart b/sdk/lib/_http/http_parser.dart
index 74582d7..a67011e 100644
--- a/sdk/lib/_http/http_parser.dart
+++ b/sdk/lib/_http/http_parser.dart
@@ -713,10 +713,10 @@
(isUpgrade && isResponse && isUpgradeCode)) {
_connectionUpgrade = true;
}
- _headers.add(headerField, tokens[i]);
+ _headers._add(headerField, tokens[i]);
}
} else {
- _headers.add(headerField, headerValue);
+ _headers._add(headerField, headerValue);
}
_headerField.clear();
_headerValue.clear();
diff --git a/sdk/lib/_internal/js_dev_runtime/patch/io_patch.dart b/sdk/lib/_internal/js_dev_runtime/patch/io_patch.dart
index 48a0969..7c14c7a 100644
--- a/sdk/lib/_internal/js_dev_runtime/patch/io_patch.dart
+++ b/sdk/lib/_internal/js_dev_runtime/patch/io_patch.dart
@@ -427,6 +427,11 @@
InternetAddress address, String host) {
throw UnsupportedError("InternetAddress._cloneWithNewHost");
}
+
+ @patch
+ static InternetAddress tryParse(String address) {
+ throw UnsupportedError("InternetAddress.tryParse");
+ }
}
@patch
diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart
index 02827b1..7d69599 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart
@@ -30,7 +30,7 @@
// Run-time null safety assertion per:
// https://github.com/dart-lang/language/blob/master/accepted/future-releases/nnbd/feature-specification.md#automatic-debug-assertion-insertion
nullFailed(String fileUri, int line, int column, String variable) {
- if (_strictSubtypeChecks) {
+ if (strictNullSafety) {
throw AssertionErrorImpl(
'A null value was passed into a non-nullable parameter $variable',
fileUri,
diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart
index 916ed53..443711a 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart
@@ -187,7 +187,7 @@
if (missingRequired.isNotEmpty) {
var error = "Dynamic call with missing required named arguments: "
"${missingRequired.join(', ')}.";
- if (!_strictSubtypeChecks) {
+ if (!strictNullSafety) {
_nullWarn(error);
} else {
return error;
@@ -432,7 +432,7 @@
cast(obj, type) {
// We hoist the common case where null is checked against another type here
// for better performance.
- if (obj == null && !_strictSubtypeChecks) {
+ if (obj == null && !strictNullSafety) {
// Check the null comparison cache to avoid emitting repeated warnings.
_nullWarnOnType(type);
return obj;
@@ -452,8 +452,7 @@
bool dtest(obj) {
// Only throw an AssertionError in weak mode for compatibility. Strong mode
// should throw a TypeError.
- if (obj is! bool)
- booleanConversionFailed(_strictSubtypeChecks ? obj : test(obj));
+ if (obj is! bool) booleanConversionFailed(strictNullSafety ? obj : test(obj));
return obj;
}
@@ -465,7 +464,7 @@
asInt(obj) {
// Note: null (and undefined) will fail this test.
if (JS('!', 'Math.floor(#) != #', obj, obj)) {
- if (obj == null && !_strictSubtypeChecks) {
+ if (obj == null && !strictNullSafety) {
_nullWarnOnType(JS('', '#', int));
return null;
} else {
@@ -498,7 +497,7 @@
/// same type.
nullCast(x, type) {
if (x == null) {
- if (!_strictSubtypeChecks) {
+ if (!strictNullSafety) {
_nullWarnOnType(type);
} else {
castError(x, type);
diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
index 5a95fef..c1235fd 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
@@ -8,13 +8,22 @@
part of dart._runtime;
@notNull
-bool _strictSubtypeChecks = false;
+bool _setNullSafety = false;
+
+@notNull
+bool strictNullSafety = false;
/// Sets the mode of the runtime subtype checks.
///
-/// Changing the mode after any calls to dart.isSubtype() is not supported.
-void strictSubtypeChecks(bool flag) {
- _strictSubtypeChecks = flag;
+/// Changing the mode after the application has started running is not
+/// supported.
+void nullSafety(bool flag) {
+ if (_setNullSafety) {
+ throw UnsupportedError('The Null Safety mode can only be set once.');
+ }
+
+ strictNullSafety = flag;
+ _setNullSafety = true;
}
final metadata = JS('', 'Symbol("metadata")');
@@ -795,15 +804,10 @@
@JSExportName('as')
as_T(obj) {
- if (JS('!', 'typeof # == "function"', obj)) {
- var actual = JS('', '#[#]', obj, _runtimeType);
- // If there's no actual type, it's a JS function.
- // Allow them to subtype all Dart function types.
- if (actual == null || isSubtypeOf(actual, this)) {
- return obj;
- }
- }
- return castError(obj, this);
+ if (is_T(obj)) return obj;
+ // TODO(nshahan) This could directly call castError after we no longer allow
+ // a cast of null to succeed in weak mode.
+ return cast(obj, this);
}
}
@@ -852,7 +856,7 @@
var bound = typeBounds[i];
if (_equalType(bound, dynamic) ||
JS<bool>('!', '# === #', bound, nullable(unwrapType(Object))) ||
- (!_strictSubtypeChecks && _equalType(bound, Object))) {
+ (!strictNullSafety && _equalType(bound, Object))) {
// Do not print the bound when it is a top type. In weak mode the bounds
// of Object and Object* will also be elided.
continue;
@@ -951,7 +955,7 @@
// difference is rare.
if (_equalType(type, dynamic)) return true;
if (_jsInstanceOf(type, NullableType) ||
- (!_strictSubtypeChecks && _jsInstanceOf(type, LegacyType))) {
+ (!strictNullSafety && _jsInstanceOf(type, LegacyType))) {
return _equalType(JS('!', '#.type', type), Object);
}
return false;
@@ -1046,7 +1050,9 @@
@JSExportName('as')
as_T(obj) {
if (is_T(obj)) return obj;
- return castError(obj, this);
+ // TODO(nshahan) This could directly call castError after we no longer allow
+ // a cast of null to succeed in weak mode.
+ return cast(obj, this);
}
}
@@ -1241,7 +1247,7 @@
if (JS('!', '# !== void 0', result)) return result;
var validSubtype = _isSubtype(t1, t2, true);
- if (!validSubtype && !_strictSubtypeChecks) {
+ if (!validSubtype && !strictNullSafety) {
validSubtype = _isSubtype(t1, t2, false);
if (validSubtype) {
// TODO(nshahan) Need more information to be helpful here.
@@ -1697,7 +1703,7 @@
var supertypeRequiredNamed = supertype.getRequiredNamedParameters();
var subtypeNamed = supertype.getNamedParameters();
var subtypeRequiredNamed = supertype.getRequiredNamedParameters();
- if (!_strictSubtypeChecks) {
+ if (!strictNullSafety) {
// In weak mode, treat required named params as optional named params.
supertypeNamed = {...supertypeNamed, ...supertypeRequiredNamed};
subtypeNamed = {...subtypeNamed, ...subtypeRequiredNamed};
diff --git a/sdk/lib/_internal/js_runtime/lib/io_patch.dart b/sdk/lib/_internal/js_runtime/lib/io_patch.dart
index 146776c..08405ab 100644
--- a/sdk/lib/_internal/js_runtime/lib/io_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/io_patch.dart
@@ -427,6 +427,11 @@
InternetAddress address, String host) {
throw new UnsupportedError("InternetAddress._cloneWithNewHost");
}
+
+ @patch
+ static InternetAddress tryParse(String address) {
+ throw new UnsupportedError("InternetAddress.tryParse");
+ }
}
@patch
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
index d0e7ee1..0600bf7 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
@@ -3551,3 +3551,9 @@
String testingGetPlatformEnvironmentVariable() {
return testPlatformEnvironmentVariableValue;
}
+
+// These are used to indicate that a named parameter is required when lazily
+// retrieving default values via [JsGetName.DEFAULT_VALUES_PROPERTY].
+class _Required {
+ const _Required();
+}
diff --git a/sdk/lib/_internal/js_runtime/lib/rti.dart b/sdk/lib/_internal/js_runtime/lib/rti.dart
index ae12f72..d89eded 100644
--- a/sdk/lib/_internal/js_runtime/lib/rti.dart
+++ b/sdk/lib/_internal/js_runtime/lib/rti.dart
@@ -1156,8 +1156,7 @@
typeParametersText += typeSep;
typeParametersText += genericContext[genericContext.length - 1 - i];
Rti boundRti = _castToRti(_Utils.arrayAt(bounds, i));
- if (!isTopType(boundRti) &&
- (!JS_GET_FLAG('LEGACY') || !isObjectType(boundRti))) {
+ if (!isTopType(boundRti)) {
typeParametersText +=
' extends ' + _rtiToString(boundRti, genericContext);
}
@@ -1684,7 +1683,7 @@
universe, Rti baseType, String key, bool normalize) {
if (normalize) {
int baseKind = Rti._getKind(baseType);
- if (isTopType(baseType) ||
+ if (isStrongTopType(baseType) ||
isNullType(baseType) ||
baseKind == Rti.kindQuestion ||
baseKind == Rti.kindStar) {
@@ -2560,11 +2559,7 @@
if (isStrongTopType(s)) return false;
// Left Bottom:
- if (isLegacy) {
- if (isNullType(s)) return true;
- } else {
- if (sKind == Rti.kindNever) return true;
- }
+ if (isBottomType(s)) return true;
// Left Type Variable Bound 1:
bool leftTypeVariable = sKind == Rti.kindGenericFunctionParameter;
@@ -2884,7 +2879,10 @@
kind == Rti.kindFutureOr && isNullable(Rti._getFutureOrArgument(t));
}
-bool isTopType(Rti t) => isStrongTopType(t) || isLegacyObjectType(t);
+bool isTopType(Rti t) =>
+ isStrongTopType(t) ||
+ isLegacyObjectType(t) ||
+ JS_GET_FLAG('LEGACY') && isObjectType(t);
bool isStrongTopType(Rti t) {
int kind = Rti._getKind(t);
@@ -2892,10 +2890,12 @@
kind == Rti.kindVoid ||
kind == Rti.kindAny ||
kind == Rti.kindErased ||
- !JS_GET_FLAG('NNBD') && isObjectType(t) ||
isNullableObjectType(t);
}
+bool isBottomType(Rti t) =>
+ Rti._getKind(t) == Rti.kindNever || JS_GET_FLAG('LEGACY') && isNullType(t);
+
bool isObjectType(Rti t) => _Utils.isIdentical(t, TYPE_REF<Object>());
bool isLegacyObjectType(Rti t) =>
_Utils.isIdentical(t, LEGACY_TYPE_REF<Object>());
diff --git a/sdk/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart b/sdk/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart
index 3b35902..62372e7 100644
--- a/sdk/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart
+++ b/sdk/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart
@@ -53,6 +53,8 @@
static const String endNamedGroupString = _rightBraceString;
static const int nameSeparator = _colon;
static const String nameSeparatorString = _colonString;
+ static const int requiredNameSeparator = _exclamation;
+ static const String requiredNameSeparatorString = _exclamationString;
static const int genericFunctionTypeParameterIndex = _circumflex;
static const String genericFunctionTypeParameterIndexString =
@@ -191,6 +193,8 @@
test("startNamedGroup", startNamedGroup, startNamedGroupString);
test("endNamedGroup", endNamedGroup, endNamedGroupString);
test("nameSeparator", nameSeparator, nameSeparatorString);
+ test("requiredNameSeparator", requiredNameSeparator,
+ requiredNameSeparatorString);
test("genericFunctionTypeParameterIndex", genericFunctionTypeParameterIndex,
genericFunctionTypeParameterIndexString);
test("extensionOp", extensionOp, extensionOpString);
diff --git a/sdk/lib/_internal/vm/bin/builtin.dart b/sdk/lib/_internal/vm/bin/builtin.dart
index b79755e..3c7f591 100644
--- a/sdk/lib/_internal/vm/bin/builtin.dart
+++ b/sdk/lib/_internal/vm/bin/builtin.dart
@@ -11,6 +11,7 @@
import 'dart:collection' hide LinkedList, LinkedListEntry;
import 'dart:_internal' hide Symbol;
import 'dart:io';
+import 'dart:convert';
import 'dart:isolate';
import 'dart:typed_data';
@@ -130,11 +131,12 @@
_log('Resolving package with uri path: ${uri.path}');
}
var resolvedUri;
- if (_packageError != null) {
+ final error = _packageError;
+ if (error != null) {
if (_traceLoading) {
- _log("Resolving package with pending resolution error: $_packageError");
+ _log("Resolving package with pending resolution error: $error");
}
- throw _packageError;
+ throw error;
} else {
if (packageNameEnd < 0) {
// Package URIs must have a path after the package name, even if it's
@@ -430,9 +432,67 @@
return result;
}
+_loadPackageConfigFile(bool traceLoading, Uri packageConfig) {
+ try {
+ final Uint8List data = File.fromUri(packageConfig).readAsBytesSync();
+ if (traceLoading) {
+ _log("Loaded package config file from $packageConfig.");
+ }
+ return _parsePackageConfig(traceLoading, packageConfig, data);
+ } catch (e, s) {
+ if (traceLoading) {
+ _log("Error loading packages: $e\n$s");
+ }
+ return "Uncaught error ($e) loading packages file.";
+ }
+}
+
+// The .dart_tool/package_config.json format is described in
+//
+// https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/package-config-file-v2.md
+//
+// The returned list has the format:
+//
+// [0] Location of package_config.json file.
+// [1] null
+// [n*2] Name of n-th package
+// [n*2 + 1] Location of n-th package's sources (as a String)
+//
+List _parsePackageConfig(
+ bool traceLoading, Uri packageConfig, Uint8List bytes) {
+ final Map packageJson = json.decode(utf8.decode(bytes));
+ final version = packageJson['configVersion'];
+ if (version != 2) {
+ throw 'The package configuration file has an unsupported version.';
+ }
+ // The first entry contains the location of the identified
+ // .dart_tool/package_config.json file instead of a mapping.
+ final result = <dynamic>[packageConfig.toString(), null];
+ final List packages = packageJson['packages'] ?? [];
+ for (final Map package in packages) {
+ final String name = package['name'];
+ final String rootUri = package['rootUri'];
+ final String packageUri = package['packageUri'];
+ final Uri resolvedRootUri = packageConfig.resolve(rootUri);
+ final Uri resolvedPackageUri = packageUri != null
+ ? resolvedRootUri.resolve(packageUri)
+ : resolvedRootUri;
+ if (packageUri != null &&
+ !'$resolvedPackageUri'.contains('$resolvedRootUri')) {
+ throw 'The resolved "packageUri" is not a subdirectory of the "rootUri".';
+ }
+ result.add(name);
+ result.add(resolvedPackageUri.toString());
+ if (traceLoading) {
+ _log('Resolved package $name to be at $resolvedPackageUri');
+ }
+ }
+ return result;
+}
+
_loadPackagesFile(bool traceLoading, Uri packagesFile) {
try {
- var data = new File.fromUri(packagesFile).readAsBytesSync();
+ final Uint8List data = File.fromUri(packagesFile).readAsBytesSync();
if (traceLoading) {
_log("Loaded packages file from $packagesFile:\n"
"${new String.fromCharCodes(data)}");
@@ -446,39 +506,49 @@
}
}
-_findPackagesFile(bool traceLoading, Uri base) {
+_findPackagesConfiguration(bool traceLoading, Uri base) {
try {
- // Walk up the directory hierarchy to check for the existence of
- // .packages files in parent directories and for the existence of a
- // packages/ directory on the first iteration.
- var dir = new File.fromUri(base).parent;
- var prev = null;
- // Keep searching until we reach the root.
- while ((prev == null) || (prev.path != dir.path)) {
- // Check for the existence of a .packages file and if it exists try to
- // load and parse it.
- var dirUri = dir.uri;
- var packagesFile = dirUri.resolve(".packages");
+ // Walk up the directory hierarchy to check for the existence of either one
+ // of
+ // - .dart_tool/package_config.json
+ // - .packages
+ var currentDir = new File.fromUri(base).parent;
+ while (true) {
+ final dirUri = currentDir.uri;
+
+ // We prefer using `.dart_tool/package_config.json` over `.packages`.
+ final packageConfig = dirUri.resolve(".dart_tool/package_config.json");
+ if (traceLoading) {
+ _log("Checking for $packageConfig file.");
+ }
+ bool exists = File.fromUri(packageConfig).existsSync();
+ if (traceLoading) {
+ _log("$packageConfig exists: $exists");
+ }
+ if (exists) {
+ return _loadPackageConfigFile(traceLoading, packageConfig);
+ }
+
+ final packagesFile = dirUri.resolve(".packages");
if (traceLoading) {
_log("Checking for $packagesFile file.");
}
- var exists = new File.fromUri(packagesFile).existsSync();
+ exists = File.fromUri(packagesFile).existsSync();
if (traceLoading) {
_log("$packagesFile exists: $exists");
}
if (exists) {
return _loadPackagesFile(traceLoading, packagesFile);
}
- // Move up one level.
- prev = dir;
- dir = dir.parent;
+ final parentDir = currentDir.parent;
+ if (dirUri == parentDir.uri) break;
+ currentDir = parentDir;
}
- // No .packages file was found.
if (traceLoading) {
- _log("Could not resolve a package location from $base");
+ _log("Could not resolve a package configuration from $base");
}
- return "Could not resolve a package location for base at $base";
+ return "Could not resolve a package configuration for base at $base";
} catch (e, s) {
if (traceLoading) {
_log("Error loading packages: $e\n$s");
@@ -509,7 +579,7 @@
try {
if (tag == -1) {
if (resource.scheme == '' || resource.scheme == 'file') {
- return _findPackagesFile(traceLoading, resource);
+ return _findPackagesConfiguration(traceLoading, resource);
} else {
return "Unsupported scheme used to locate .packages file:'$resource'.";
}
@@ -580,6 +650,9 @@
}
// Embedder Entrypoint:
+// The embedder calls this method with the value of the --packages command line
+// option. It can point to a ".packages" or a ".dart_tool/package_config.json"
+// file.
@pragma("vm:entry-point")
String _setPackagesMap(String packagesParam) {
if (!_setupCompleted) {
diff --git a/sdk/lib/_internal/vm/bin/socket_patch.dart b/sdk/lib/_internal/vm/bin/socket_patch.dart
index 88b0b38..94d6903 100644
--- a/sdk/lib/_internal/vm/bin/socket_patch.dart
+++ b/sdk/lib/_internal/vm/bin/socket_patch.dart
@@ -92,6 +92,11 @@
InternetAddress address, String host) {
return (address as _InternetAddress)._cloneWithNewHost(host);
}
+
+ @patch
+ static InternetAddress tryParse(String address) {
+ return _InternetAddress.tryParse(address);
+ }
}
@patch
@@ -253,6 +258,18 @@
}
}
+ static _InternetAddress tryParse(String address) {
+ if (address == null) {
+ throw ArgumentError("Invalid internet address $address");
+ }
+ var addressBytes = _parse(address);
+ if (addressBytes == null) return null;
+ var type = addressBytes.length == _IPv4AddrLength
+ ? InternetAddressType.IPv4
+ : InternetAddressType.IPv6;
+ return _InternetAddress(type, address, null, addressBytes);
+ }
+
factory _InternetAddress.fixed(int id) {
switch (id) {
case _addressLoopbackIPv4:
diff --git a/sdk/lib/_internal/vm/lib/internal_patch.dart b/sdk/lib/_internal/vm/lib/internal_patch.dart
index 6accfc3..76a8a88 100644
--- a/sdk/lib/_internal/vm/lib/internal_patch.dart
+++ b/sdk/lib/_internal/vm/lib/internal_patch.dart
@@ -48,7 +48,6 @@
// Implementation of package root/map provision.
static var packageRootString;
static var packageConfigString;
- static var packageRootUriFuture;
static var packageConfigUriFuture;
static var resolvePackageUriFuture;
diff --git a/sdk/lib/_internal/vm/lib/isolate_patch.dart b/sdk/lib/_internal/vm/lib/isolate_patch.dart
index e17c1de..e357b8a 100644
--- a/sdk/lib/_internal/vm/lib/isolate_patch.dart
+++ b/sdk/lib/_internal/vm/lib/isolate_patch.dart
@@ -267,21 +267,21 @@
// The control port (aka the main isolate port) does not handle any messages.
if (controlPort != null) {
controlPort.handler = (_) {}; // Nobody home on the control port.
- }
- if (parentPort != null) {
- // Build a message to our parent isolate providing access to the
- // current isolate's control port and capabilities.
- //
- // TODO(floitsch): Send an error message if we can't find the entry point.
- var readyMessage = new List(2);
- readyMessage[0] = controlPort.sendPort;
- readyMessage[1] = capabilities;
+ if (parentPort != null) {
+ // Build a message to our parent isolate providing access to the
+ // current isolate's control port and capabilities.
+ //
+ // TODO(floitsch): Send an error message if we can't find the entry point.
+ final readyMessage = List(2);
+ readyMessage[0] = controlPort.sendPort;
+ readyMessage[1] = capabilities;
- // Out of an excess of paranoia we clear the capabilities from the
- // stack. Not really necessary.
- capabilities = null;
- parentPort.send(readyMessage);
+ // Out of an excess of paranoia we clear the capabilities from the
+ // stack. Not really necessary.
+ capabilities = null;
+ parentPort.send(readyMessage);
+ }
}
assert(capabilities == null);
@@ -343,7 +343,6 @@
}
static bool _packageSupported() =>
- (VMLibraryHooks.packageRootUriFuture != null) &&
(VMLibraryHooks.packageConfigUriFuture != null) &&
(VMLibraryHooks.resolvePackageUriFuture != null);
@@ -355,46 +354,33 @@
SendPort onError,
String debugName}) async {
// `paused` isn't handled yet.
- RawReceivePort readyPort;
+ // Check for the type of `entryPoint` on the spawning isolate to make
+ // error-handling easier.
+ if (entryPoint is! _UnaryFunction) {
+ throw new ArgumentError(entryPoint);
+ }
+ // The VM will invoke [_startIsolate] with entryPoint as argument.
+
+ // We do not inherit the package config settings from the parent isolate,
+ // instead we use the values that were set on the command line.
+ var packageConfig = VMLibraryHooks.packageConfigString;
+ var script = VMLibraryHooks.platformScript;
+ if (script == null) {
+ // We do not have enough information to support spawning the new
+ // isolate.
+ throw new UnsupportedError("Isolate.spawn");
+ }
+ if (script.isScheme("package")) {
+ script = await Isolate.resolvePackageUri(script);
+ }
+
+ final RawReceivePort readyPort = new RawReceivePort();
try {
- // Check for the type of `entryPoint` on the spawning isolate to make
- // error-handling easier.
- if (entryPoint is! _UnaryFunction) {
- throw new ArgumentError(entryPoint);
- }
- // The VM will invoke [_startIsolate] with entryPoint as argument.
- readyPort = new RawReceivePort();
-
- // We do not inherit the package config settings from the parent isolate,
- // instead we use the values that were set on the command line.
- var packageConfig = VMLibraryHooks.packageConfigString;
- var script = VMLibraryHooks.platformScript;
- if (script == null) {
- // We do not have enough information to support spawning the new
- // isolate.
- throw new UnsupportedError("Isolate.spawn");
- }
- if (script.scheme == "package") {
- script = await Isolate.resolvePackageUri(script);
- }
-
- _spawnFunction(
- readyPort.sendPort,
- script.toString(),
- entryPoint,
- message,
- paused,
- errorsAreFatal,
- onExit,
- onError,
- null,
- packageConfig,
- debugName);
+ _spawnFunction(readyPort.sendPort, script.toString(), entryPoint, message,
+ paused, errorsAreFatal, onExit, onError, packageConfig, debugName);
return await _spawnCommon(readyPort);
} catch (e, st) {
- if (readyPort != null) {
- readyPort.close();
- }
+ readyPort.close();
return await new Future<Isolate>.error(e, st);
}
}
@@ -411,7 +397,6 @@
Uri packageConfig,
bool automaticPackageResolution: false,
String debugName}) async {
- RawReceivePort readyPort;
if (environment != null) {
throw new UnimplementedError("environment");
}
@@ -434,38 +419,30 @@
"packageRoot and a packageConfig.");
}
}
+ // Resolve the uri against the current isolate's root Uri first.
+ final Uri spawnedUri = _rootUri.resolveUri(uri);
+
+ // Inherit this isolate's package resolution setup if not overridden.
+ if (!automaticPackageResolution && packageConfig == null) {
+ if (Isolate._packageSupported()) {
+ packageConfig = await Isolate.packageConfig;
+ }
+ }
+
+ // Ensure to resolve package: URIs being handed in as parameters.
+ if (packageConfig != null) {
+ // Avoid calling resolvePackageUri if not strictly necessary in case
+ // the API is not supported.
+ if (packageConfig.isScheme("package")) {
+ packageConfig = await Isolate.resolvePackageUri(packageConfig);
+ }
+ }
+
+ // The VM will invoke [_startIsolate] and not `main`.
+ final packageConfigString = packageConfig?.toString();
+
+ final RawReceivePort readyPort = new RawReceivePort();
try {
- // Resolve the uri against the current isolate's root Uri first.
- var spawnedUri = _rootUri.resolveUri(uri);
-
- // Inherit this isolate's package resolution setup if not overridden.
- if (!automaticPackageResolution &&
- (packageRoot == null) &&
- (packageConfig == null)) {
- if (Isolate._packageSupported()) {
- packageRoot = await Isolate.packageRoot;
- packageConfig = await Isolate.packageConfig;
- }
- }
-
- // Ensure to resolve package: URIs being handed in as parameters.
- if (packageRoot != null) {
- // `packages/` directory is no longer supported. Force it null.
- // TODO(mfairhurst) Should this throw an exception?
- packageRoot = null;
- } else if (packageConfig != null) {
- // Avoid calling resolvePackageUri if not strictly necessary in case
- // the API is not supported.
- if (packageConfig.scheme == "package") {
- packageConfig = await Isolate.resolvePackageUri(packageConfig);
- }
- }
-
- // The VM will invoke [_startIsolate] and not `main`.
- readyPort = new RawReceivePort();
- var packageRootString = packageRoot?.toString();
- var packageConfigString = packageConfig?.toString();
-
_spawnUri(
readyPort.sendPort,
spawnedUri.toString(),
@@ -478,20 +455,17 @@
checked,
null,
/* environment */
- packageRootString,
packageConfigString,
debugName);
return await _spawnCommon(readyPort);
} catch (e) {
- if (readyPort != null) {
- readyPort.close();
- }
+ readyPort.close();
rethrow;
}
}
static Future<Isolate> _spawnCommon(RawReceivePort readyPort) {
- Completer completer = new Completer<Isolate>.sync();
+ final completer = new Completer<Isolate>.sync();
readyPort.handler = (readyMessage) {
readyPort.close();
if (readyMessage is List && readyMessage.length == 2) {
@@ -536,7 +510,6 @@
bool errorsAreFatal,
SendPort onExit,
SendPort onError,
- String packageRoot,
String packageConfig,
String debugName) native "Isolate_spawnFunction";
@@ -551,7 +524,6 @@
bool errorsAreFatal,
bool checked,
List environment,
- String packageRoot,
String packageConfig,
String debugName) native "Isolate_spawnUri";
diff --git a/sdk/lib/io/socket.dart b/sdk/lib/io/socket.dart
index 283a30a..c030553 100644
--- a/sdk/lib/io/socket.dart
+++ b/sdk/lib/io/socket.dart
@@ -215,6 +215,12 @@
*/
external static InternetAddress _cloneWithNewHost(
InternetAddress address, String host);
+
+ /// Attempts to parse [address] as a numeric address.
+ ///
+ /// Returns `null` if [address] is not a numeric IPv4 (dotted-decimal
+ /// notation) or IPv6 (hexadecimal representation) address.
+ external static InternetAddress tryParse(String address);
}
/**
diff --git a/sdk_nnbd/lib/_http/http_parser.dart b/sdk_nnbd/lib/_http/http_parser.dart
index 96891a1..9459789 100644
--- a/sdk_nnbd/lib/_http/http_parser.dart
+++ b/sdk_nnbd/lib/_http/http_parser.dart
@@ -713,10 +713,10 @@
(isUpgrade && isResponse && isUpgradeCode)) {
_connectionUpgrade = true;
}
- headers.add(headerField, tokens[i]);
+ headers._add(headerField, tokens[i]);
}
} else {
- headers.add(headerField, headerValue);
+ headers._add(headerField, headerValue);
}
_headerField.clear();
_headerValue.clear();
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/internal_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/internal_patch.dart
index 4d6a130..2e605a2 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/internal_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/internal_patch.dart
@@ -10,13 +10,8 @@
import 'dart:_foreign_helper' show JS;
import 'dart:_runtime' as dart;
-// TODO(41657) Make a constant when CFE evaluates in the null safety mode.
-var isLegacySubtyping = const <Null>[] is List<int>;
-
@patch
-bool typeAcceptsNull<T>() {
- return isLegacySubtyping || null is T;
-}
+bool typeAcceptsNull<T>() => !dart.strictNullSafety || null is T;
@patch
class Symbol implements core.Symbol {
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/io_patch.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/io_patch.dart
index ceee3d4..980adde 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/patch/io_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/patch/io_patch.dart
@@ -425,6 +425,11 @@
InternetAddress address, String host) {
throw UnsupportedError("InternetAddress._cloneWithNewHost");
}
+
+ @patch
+ static InternetAddress? tryParse(String address) {
+ throw UnsupportedError("InternetAddress.tryParse");
+ }
}
@patch
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart
index 5696d69..ba418a4 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart
@@ -28,7 +28,7 @@
// Run-time null safety assertion per:
// https://github.com/dart-lang/language/blob/master/accepted/future-releases/nnbd/feature-specification.md#automatic-debug-assertion-insertion
nullFailed(String? fileUri, int? line, int? column, String? variable) {
- if (_strictSubtypeChecks) {
+ if (strictNullSafety) {
throw AssertionErrorImpl(
'A null value was passed into a non-nullable parameter $variable',
fileUri,
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart
index b325083..43697c9 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart
@@ -185,7 +185,7 @@
if (missingRequired.isNotEmpty) {
var error = "Dynamic call with missing required named arguments: "
"${missingRequired.join(', ')}.";
- if (!_strictSubtypeChecks) {
+ if (!strictNullSafety) {
_nullWarn(error);
} else {
return error;
@@ -430,7 +430,7 @@
cast(obj, type) {
// We hoist the common case where null is checked against another type here
// for better performance.
- if (obj == null && !_strictSubtypeChecks) {
+ if (obj == null && !strictNullSafety) {
// Check the null comparison cache to avoid emitting repeated warnings.
_nullWarnOnType(type);
return obj;
@@ -450,8 +450,7 @@
bool dtest(obj) {
// Only throw an AssertionError in weak mode for compatibility. Strong mode
// should throw a TypeError.
- if (obj is! bool)
- booleanConversionFailed(_strictSubtypeChecks ? obj : test(obj));
+ if (obj is! bool) booleanConversionFailed(strictNullSafety ? obj : test(obj));
return obj;
}
@@ -463,7 +462,7 @@
asInt(obj) {
// Note: null (and undefined) will fail this test.
if (JS('!', 'Math.floor(#) != #', obj, obj)) {
- if (obj == null && !_strictSubtypeChecks) {
+ if (obj == null && !strictNullSafety) {
_nullWarnOnType(JS('', '#', int));
return null;
} else {
@@ -496,7 +495,7 @@
/// same type.
nullCast(x, type) {
if (x == null) {
- if (!_strictSubtypeChecks) {
+ if (!strictNullSafety) {
_nullWarnOnType(type);
} else {
castError(x, type);
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
index 4d404ae..b985e78 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
@@ -6,13 +6,22 @@
part of dart._runtime;
@notNull
-bool _strictSubtypeChecks = false;
+bool _setNullSafety = false;
+
+@notNull
+bool strictNullSafety = false;
/// Sets the mode of the runtime subtype checks.
///
-/// Changing the mode after any calls to dart.isSubtype() is not supported.
-void strictSubtypeChecks(bool flag) {
- _strictSubtypeChecks = flag;
+/// Changing the mode after the application has started running is not
+/// supported.
+void nullSafety(bool flag) {
+ if (_setNullSafety) {
+ throw UnsupportedError('The Null Safety mode can only be set once.');
+ }
+
+ strictNullSafety = flag;
+ _setNullSafety = true;
}
final metadata = JS('', 'Symbol("metadata")');
@@ -793,15 +802,10 @@
@JSExportName('as')
as_T(obj) {
- if (JS('!', 'typeof # == "function"', obj)) {
- var actual = JS('', '#[#]', obj, _runtimeType);
- // If there's no actual type, it's a JS function.
- // Allow them to subtype all Dart function types.
- if (actual == null || isSubtypeOf(actual, this)) {
- return obj;
- }
- }
- return castError(obj, this);
+ if (is_T(obj)) return obj;
+ // TODO(nshahan) This could directly call castError after we no longer allow
+ // a cast of null to succeed in weak mode.
+ return cast(obj, this);
}
}
@@ -850,7 +854,7 @@
var bound = typeBounds[i];
if (_equalType(bound, dynamic) ||
JS<bool>('!', '# === #', bound, nullable(unwrapType(Object))) ||
- (!_strictSubtypeChecks && _equalType(bound, Object))) {
+ (!strictNullSafety && _equalType(bound, Object))) {
// Do not print the bound when it is a top type. In weak mode the bounds
// of Object and Object* will also be elided.
continue;
@@ -949,7 +953,7 @@
// difference is rare.
if (_equalType(type, dynamic)) return true;
if (_jsInstanceOf(type, NullableType) ||
- (!_strictSubtypeChecks && _jsInstanceOf(type, LegacyType))) {
+ (!strictNullSafety && _jsInstanceOf(type, LegacyType))) {
return _equalType(JS('!', '#.type', type), Object);
}
return false;
@@ -1044,7 +1048,9 @@
@JSExportName('as')
as_T(obj) {
if (is_T(obj)) return obj;
- return castError(obj, this);
+ // TODO(nshahan) This could directly call castError after we no longer allow
+ // a cast of null to succeed in weak mode.
+ return cast(obj, this);
}
}
@@ -1239,7 +1245,7 @@
if (JS('!', '# !== void 0', result)) return result;
var validSubtype = _isSubtype(t1, t2, true);
- if (!validSubtype && !_strictSubtypeChecks) {
+ if (!validSubtype && !strictNullSafety) {
validSubtype = _isSubtype(t1, t2, false);
if (validSubtype) {
// TODO(nshahan) Need more information to be helpful here.
@@ -1695,7 +1701,7 @@
var supertypeRequiredNamed = supertype.getRequiredNamedParameters();
var subtypeNamed = supertype.getNamedParameters();
var subtypeRequiredNamed = supertype.getRequiredNamedParameters();
- if (!_strictSubtypeChecks) {
+ if (!strictNullSafety) {
// In weak mode, treat required named params as optional named params.
supertypeNamed = {...supertypeNamed, ...supertypeRequiredNamed};
subtypeNamed = {...subtypeNamed, ...subtypeRequiredNamed};
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/io_patch.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/io_patch.dart
index da7ebc7..ab539ed 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/io_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/io_patch.dart
@@ -425,6 +425,11 @@
InternetAddress address, String host) {
throw new UnsupportedError("InternetAddress._cloneWithNewHost");
}
+
+ @patch
+ static InternetAddress? tryParse(String address) {
+ throw UnsupportedError("InternetAddress.tryParse");
+ }
}
@patch
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/js_helper.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/js_helper.dart
index 9c74300..aeca848 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/js_helper.dart
@@ -1189,7 +1189,11 @@
List keys = JS('JSArray', r'Object.keys(#)', defaultValues);
if (namedArguments == null) {
for (String key in keys) {
- arguments.add(JS('var', '#[#]', defaultValues, key));
+ var defaultValue = JS('var', '#[#]', defaultValues, key);
+ if (isRequired(defaultValue)) {
+ return functionNoSuchMethod(function, arguments, namedArguments);
+ }
+ arguments.add(defaultValue);
}
} else {
int used = 0;
@@ -1198,7 +1202,11 @@
used++;
arguments.add(namedArguments[key]);
} else {
- arguments.add(JS('var', r'#[#]', defaultValues, key));
+ var defaultValue = JS('var', '#[#]', defaultValues, key);
+ if (isRequired(defaultValue)) {
+ return functionNoSuchMethod(function, arguments, namedArguments);
+ }
+ arguments.add(defaultValue);
}
}
if (used != namedArguments.length) {
@@ -3550,3 +3558,12 @@
String testingGetPlatformEnvironmentVariable() {
return testPlatformEnvironmentVariableValue;
}
+
+// These are used to indicate that a named parameter is required when lazily
+// retrieving default values via [JsGetName.DEFAULT_VALUES_PROPERTY].
+class _Required {
+ const _Required();
+}
+
+const kRequiredSentinel = const _Required();
+bool isRequired(Object? value) => identical(kRequiredSentinel, value);
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart
index e35aa06..b29e59c 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart
@@ -350,8 +350,6 @@
}
class _FunctionParameters {
- // TODO(fishythefish): Support required named parameters.
-
static _FunctionParameters allocate() => _FunctionParameters();
Object? _requiredPositional;
@@ -370,21 +368,21 @@
parameters._optionalPositional = optionalPositional;
}
- /// These are alternating name/type pairs; that is, the optional named
- /// parameters of the function
+ /// These are a sequence of name/bool/type triplets that correspond to named
+ /// parameters.
///
- /// void foo({int bar, double baz})
+ /// void foo({int bar, required double baz})
///
- /// would be encoded as ["bar", int, "baz", double], where the even indices are
- /// the name [String]s and the odd indices are the type [Rti]s.
+ /// would be encoded as ["bar", false, int, "baz", true, double], where each
+ /// triplet consists of the name [String], a bool indicating whether or not
+ /// the parameter is required, and the [Rti].
///
- /// Invariant: These pairs are sorted by name in lexicographically ascending order.
- Object? _optionalNamed;
- static JSArray _getOptionalNamed(_FunctionParameters parameters) =>
- JS('JSUnmodifiableArray', '#', parameters._optionalNamed);
- static void _setOptionalNamed(
- _FunctionParameters parameters, Object? optionalNamed) {
- parameters._optionalNamed = optionalNamed;
+ /// Invariant: These groups are sorted by name in lexicographically ascending order.
+ Object? _named;
+ static JSArray _getNamed(_FunctionParameters parameters) =>
+ JS('JSUnmodifiableArray', '#', parameters._named);
+ static void _setNamed(_FunctionParameters parameters, Object? named) {
+ parameters._named = named;
}
}
@@ -573,22 +571,23 @@
Object? universe, Object? namedArray, Object? typeArguments, int depth) {
bool changed = false;
int length = _Utils.arrayLength(namedArray);
- assert(length.isEven);
+ assert(length % 3 == 0);
Object? result = JS('', '[]');
- for (int i = 0; i < length; i += 2) {
+ for (int i = 0; i < length; i += 3) {
String name = _Utils.asString(_Utils.arrayAt(namedArray, i));
- Rti rti = _Utils.asRti(_Utils.arrayAt(namedArray, i + 1));
+ bool isRequired = _Utils.asBool(_Utils.arrayAt(namedArray, i + 1));
+ Rti rti = _Utils.asRti(_Utils.arrayAt(namedArray, i + 2));
Rti substitutedRti = _substitute(universe, rti, typeArguments, depth);
if (_Utils.isNotIdentical(substitutedRti, rti)) {
changed = true;
}
_Utils.arrayPush(result, name);
+ _Utils.arrayPush(result, isRequired);
_Utils.arrayPush(result, substitutedRti);
}
return changed ? result : namedArray;
}
-// TODO(fishythefish): Support required named parameters.
_FunctionParameters _substituteFunctionParameters(Object? universe,
_FunctionParameters functionParameters, Object? typeArguments, int depth) {
var requiredPositional =
@@ -599,19 +598,18 @@
_FunctionParameters._getOptionalPositional(functionParameters);
var substitutedOptionalPositional =
_substituteArray(universe, optionalPositional, typeArguments, depth);
- var optionalNamed = _FunctionParameters._getOptionalNamed(functionParameters);
- var substitutedOptionalNamed =
- _substituteNamed(universe, optionalNamed, typeArguments, depth);
+ var named = _FunctionParameters._getNamed(functionParameters);
+ var substitutedNamed =
+ _substituteNamed(universe, named, typeArguments, depth);
if (_Utils.isIdentical(substitutedRequiredPositional, requiredPositional) &&
_Utils.isIdentical(substitutedOptionalPositional, optionalPositional) &&
- _Utils.isIdentical(substitutedOptionalNamed, optionalNamed))
- return functionParameters;
+ _Utils.isIdentical(substitutedNamed, named)) return functionParameters;
_FunctionParameters result = _FunctionParameters.allocate();
_FunctionParameters._setRequiredPositional(
result, substitutedRequiredPositional);
_FunctionParameters._setOptionalPositional(
result, substitutedOptionalPositional);
- _FunctionParameters._setOptionalNamed(result, substitutedOptionalNamed);
+ _FunctionParameters._setNamed(result, substitutedNamed);
return result;
}
@@ -1253,8 +1251,7 @@
typeParametersText += typeSep;
typeParametersText += genericContext[genericContext.length - 1 - i];
Rti boundRti = _Utils.asRti(_Utils.arrayAt(bounds, i));
- if (!isTopType(boundRti) &&
- (!JS_GET_FLAG('LEGACY') || !isObjectType(boundRti))) {
+ if (!isTopType(boundRti)) {
typeParametersText +=
' extends ' + _rtiToString(boundRti, genericContext);
}
@@ -1263,7 +1260,6 @@
typeParametersText += '>';
}
- // TODO(fishythefish): Support required named parameters.
Rti returnType = Rti._getReturnType(functionType);
_FunctionParameters parameters = Rti._getFunctionParameters(functionType);
var requiredPositional =
@@ -1272,9 +1268,9 @@
var optionalPositional =
_FunctionParameters._getOptionalPositional(parameters);
int optionalPositionalLength = _Utils.arrayLength(optionalPositional);
- var optionalNamed = _FunctionParameters._getOptionalNamed(parameters);
- int optionalNamedLength = _Utils.arrayLength(optionalNamed);
- assert(optionalPositionalLength == 0 || optionalNamedLength == 0);
+ var named = _FunctionParameters._getNamed(parameters);
+ int namedLength = _Utils.arrayLength(named);
+ assert(optionalPositionalLength == 0 || namedLength == 0);
String returnTypeText = _rtiToString(returnType, genericContext);
@@ -1299,15 +1295,18 @@
argumentsText += ']';
}
- if (optionalNamedLength > 0) {
+ if (namedLength > 0) {
argumentsText += sep + '{';
sep = '';
- for (int i = 0; i < optionalNamedLength; i += 2) {
- argumentsText += sep +
- _rtiToString(_Utils.asRti(_Utils.arrayAt(optionalNamed, i + 1)),
- genericContext) +
+ for (int i = 0; i < namedLength; i += 3) {
+ argumentsText += sep;
+ if (_Utils.asBool(_Utils.arrayAt(named, i + 1))) {
+ argumentsText += 'required ';
+ }
+ argumentsText += _rtiToString(
+ _Utils.asRti(_Utils.arrayAt(named, i + 2)), genericContext) +
' ' +
- _Utils.asString(_Utils.arrayAt(optionalNamed, i));
+ _Utils.asString(_Utils.arrayAt(named, i));
sep = ', ';
}
argumentsText += '}';
@@ -1411,7 +1410,6 @@
}
String functionParametersToString(_FunctionParameters parameters) {
- // TODO(fishythefish): Support required named parameters.
String s = '(', sep = '';
var requiredPositional =
_FunctionParameters._getRequiredPositional(parameters);
@@ -1419,9 +1417,9 @@
var optionalPositional =
_FunctionParameters._getOptionalPositional(parameters);
int optionalPositionalLength = _Utils.arrayLength(optionalPositional);
- var optionalNamed = _FunctionParameters._getOptionalNamed(parameters);
- int optionalNamedLength = _Utils.arrayLength(optionalNamed);
- assert(optionalPositionalLength == 0 || optionalNamedLength == 0);
+ var named = _FunctionParameters._getNamed(parameters);
+ int namedLength = _Utils.arrayLength(named);
+ assert(optionalPositionalLength == 0 || namedLength == 0);
for (int i = 0; i < requiredPositionalLength; i++) {
s += sep +
@@ -1441,15 +1439,17 @@
s += ']';
}
- if (optionalNamedLength > 0) {
+ if (namedLength > 0) {
s += sep + '{';
sep = '';
- for (int i = 0; i < optionalNamedLength; i += 2) {
- s += sep +
- _rtiToDebugString(
- _Utils.asRti(_Utils.arrayAt(optionalNamed, i + 1))) +
+ for (int i = 0; i < namedLength; i += 3) {
+ s += sep;
+ if (_Utils.asBool(_Utils.arrayAt(named, i + 1))) {
+ s += 'required ';
+ }
+ s += _rtiToDebugString(_Utils.asRti(_Utils.arrayAt(named, i + 2))) +
' ' +
- _Utils.asString(_Utils.arrayAt(optionalNamed, i));
+ _Utils.asString(_Utils.arrayAt(named, i));
sep = ', ';
}
s += '}';
@@ -1778,7 +1778,7 @@
Object? universe, Rti baseType, String key, bool normalize) {
if (normalize) {
int baseKind = Rti._getKind(baseType);
- if (isTopType(baseType) ||
+ if (isStrongTopType(baseType) ||
isNullType(baseType) ||
baseKind == Rti.kindQuestion ||
baseKind == Rti.kindStar) {
@@ -1897,12 +1897,17 @@
static String _canonicalRecipeJoinNamed(Object? arguments) {
String s = '', sep = '';
int length = _Utils.arrayLength(arguments);
- assert(length.isEven);
- for (int i = 0; i < length; i += 2) {
+ assert(length % 3 == 0);
+ for (int i = 0; i < length; i += 3) {
+ s += sep;
String name = _Utils.asString(_Utils.arrayAt(arguments, i));
- Rti type = _Utils.asRti(_Utils.arrayAt(arguments, i + 1));
+ bool isRequired = _Utils.asBool(_Utils.arrayAt(arguments, i + 1));
+ String nameSep = isRequired
+ ? Recipe.requiredNameSeparatorString
+ : Recipe.nameSeparatorString;
+ Rti type = _Utils.asRti(_Utils.arrayAt(arguments, i + 2));
String subrecipe = Rti._getCanonicalRecipe(type);
- s += sep + name + Recipe.nameSeparatorString + subrecipe;
+ s += name + nameSep + subrecipe;
sep = Recipe.separatorString;
}
return s;
@@ -1990,7 +1995,6 @@
Rti._getCanonicalRecipe(returnType) +
_canonicalRecipeOfFunctionParameters(parameters);
- // TODO(fishythefish): Support required named parameters.
static String _canonicalRecipeOfFunctionParameters(
_FunctionParameters parameters) {
var requiredPositional =
@@ -1999,9 +2003,9 @@
var optionalPositional =
_FunctionParameters._getOptionalPositional(parameters);
int optionalPositionalLength = _Utils.arrayLength(optionalPositional);
- var optionalNamed = _FunctionParameters._getOptionalNamed(parameters);
- int optionalNamedLength = _Utils.arrayLength(optionalNamed);
- assert(optionalPositionalLength == 0 || optionalNamedLength == 0);
+ var named = _FunctionParameters._getNamed(parameters);
+ int namedLength = _Utils.arrayLength(named);
+ assert(optionalPositionalLength == 0 || namedLength == 0);
String recipe = Recipe.startFunctionArgumentsString +
_canonicalRecipeJoin(requiredPositional);
@@ -2014,11 +2018,11 @@
Recipe.endOptionalGroupString;
}
- if (optionalNamedLength > 0) {
+ if (namedLength > 0) {
String sep = requiredPositionalLength > 0 ? Recipe.separatorString : '';
recipe += sep +
Recipe.startNamedGroupString +
- _canonicalRecipeJoinNamed(optionalNamed) +
+ _canonicalRecipeJoinNamed(named) +
Recipe.endNamedGroupString;
}
@@ -2277,6 +2281,11 @@
break;
case Recipe.nameSeparator:
+ push(stack, false);
+ break;
+
+ case Recipe.requiredNameSeparator:
+ push(stack, true);
break;
case Recipe.toType:
@@ -2443,13 +2452,13 @@
}
static const int optionalPositionalSentinel = -1;
- static const int optionalNamedSentinel = -2;
+ static const int namedSentinel = -2;
static void handleFunctionArguments(Object? parser, Object? stack) {
var universe = _Parser.universe(parser);
_FunctionParameters parameters = _FunctionParameters.allocate();
Object? optionalPositional = _Universe.sharedEmptyArray(universe);
- Object? optionalNamed = _Universe.sharedEmptyArray(universe);
+ Object? named = _Universe.sharedEmptyArray(universe);
var head = pop(stack);
if (_Utils.isNum(head)) {
@@ -2459,8 +2468,8 @@
optionalPositional = pop(stack);
break;
- case optionalNamedSentinel:
- optionalNamed = pop(stack);
+ case namedSentinel:
+ named = pop(stack);
break;
default:
@@ -2474,7 +2483,7 @@
_FunctionParameters._setRequiredPositional(
parameters, collectArray(parser, stack));
_FunctionParameters._setOptionalPositional(parameters, optionalPositional);
- _FunctionParameters._setOptionalNamed(parameters, optionalNamed);
+ _FunctionParameters._setNamed(parameters, named);
Rti returnType = toType(universe, environment(parser), pop(stack));
push(stack, _Universe._lookupFunctionRti(universe, returnType, parameters));
}
@@ -2488,7 +2497,7 @@
static void handleNamedGroup(Object? parser, Object? stack) {
var parameters = collectNamed(parser, stack);
push(stack, parameters);
- push(stack, optionalNamedSentinel);
+ push(stack, namedSentinel);
}
static void handleExtendedOperations(Object? parser, Object? stack) {
@@ -2543,8 +2552,8 @@
static void toTypesNamed(Object? universe, Rti environment, Object? items) {
int length = _Utils.arrayLength(items);
- assert(length.isEven);
- for (int i = 1; i < length; i += 2) {
+ assert(length % 3 == 0);
+ for (int i = 2; i < length; i += 3) {
var item = _Utils.arrayAt(items, i);
Rti type = toType(universe, environment, item);
_Utils.arraySetAt(items, i, type);
@@ -2654,11 +2663,7 @@
if (isStrongTopType(s)) return false;
// Left Bottom:
- if (isLegacy) {
- if (isNullType(s)) return true;
- } else {
- if (sKind == Rti.kindNever) return true;
- }
+ if (isBottomType(s)) return true;
// Left Type Variable Bound 1:
bool leftTypeVariable = sKind == Rti.kindGenericFunctionParameter;
@@ -2799,7 +2804,6 @@
return false;
}
-// TODO(fishythefish): Support required named parameters.
bool _isFunctionSubtype(
Object? universe, Rti s, Object? sEnv, Rti t, Object? tEnv) {
assert(Rti._getKind(s) == Rti.kindFunction);
@@ -2859,25 +2863,36 @@
}
}
- var sOptionalNamed = _FunctionParameters._getOptionalNamed(sParameters);
- var tOptionalNamed = _FunctionParameters._getOptionalNamed(tParameters);
- int sOptionalNamedLength = _Utils.arrayLength(sOptionalNamed);
- int tOptionalNamedLength = _Utils.arrayLength(tOptionalNamed);
+ var sNamed = _FunctionParameters._getNamed(sParameters);
+ var tNamed = _FunctionParameters._getNamed(tParameters);
+ int sNamedLength = _Utils.arrayLength(sNamed);
+ int tNamedLength = _Utils.arrayLength(tNamed);
- for (int i = 0, j = 0; j < tOptionalNamedLength; j += 2) {
- String sName;
- String tName = _Utils.asString(_Utils.arrayAt(tOptionalNamed, j));
- do {
- if (i >= sOptionalNamedLength) return false;
- sName = _Utils.asString(_Utils.arrayAt(sOptionalNamed, i));
- i += 2;
- } while (_Utils.stringLessThan(sName, tName));
- if (_Utils.stringLessThan(tName, sName)) return false;
- Rti sType = _Utils.asRti(_Utils.arrayAt(sOptionalNamed, i - 1));
- Rti tType = _Utils.asRti(_Utils.arrayAt(tOptionalNamed, j + 1));
- if (!_isSubtype(universe, tType, tEnv, sType, sEnv)) return false;
+ int sIndex = 0;
+ for (int tIndex = 0; tIndex < tNamedLength; tIndex += 3) {
+ String tName = _Utils.asString(_Utils.arrayAt(tNamed, tIndex));
+ while (true) {
+ if (sIndex >= sNamedLength) return false;
+ String sName = _Utils.asString(_Utils.arrayAt(sNamed, sIndex));
+ sIndex += 3;
+ if (_Utils.stringLessThan(tName, sName)) return false;
+ bool sIsRequired = _Utils.asBool(_Utils.arrayAt(sNamed, sIndex - 2));
+ if (_Utils.stringLessThan(sName, tName)) {
+ if (sIsRequired) return false;
+ continue;
+ }
+ bool tIsRequired = _Utils.asBool(_Utils.arrayAt(tNamed, tIndex + 1));
+ if (sIsRequired && !tIsRequired) return false;
+ Rti sType = _Utils.asRti(_Utils.arrayAt(sNamed, sIndex - 1));
+ Rti tType = _Utils.asRti(_Utils.arrayAt(tNamed, tIndex + 2));
+ if (!_isSubtype(universe, tType, tEnv, sType, sEnv)) return false;
+ break;
+ }
}
-
+ while (sIndex < sNamedLength) {
+ if (_Utils.asBool(_Utils.arrayAt(sNamed, sIndex + 1))) return false;
+ sIndex += 3;
+ }
return true;
}
@@ -2980,7 +2995,10 @@
kind == Rti.kindFutureOr && isNullable(Rti._getFutureOrArgument(t));
}
-bool isTopType(Rti t) => isStrongTopType(t) || isLegacyObjectType(t);
+bool isTopType(Rti t) =>
+ isStrongTopType(t) ||
+ isLegacyObjectType(t) ||
+ JS_GET_FLAG('LEGACY') && isObjectType(t);
bool isStrongTopType(Rti t) {
int kind = Rti._getKind(t);
@@ -2988,10 +3006,12 @@
kind == Rti.kindVoid ||
kind == Rti.kindAny ||
kind == Rti.kindErased ||
- !JS_GET_FLAG('NNBD') && isObjectType(t) ||
isNullableObjectType(t);
}
+bool isBottomType(Rti t) =>
+ Rti._getKind(t) == Rti.kindNever || JS_GET_FLAG('LEGACY') && isNullType(t);
+
bool isObjectType(Rti t) => _Utils.isIdentical(t, TYPE_REF<Object>());
bool isLegacyObjectType(Rti t) =>
_Utils.isIdentical(t, LEGACY_TYPE_REF<Object>());
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart
index ef7fbff..c183861 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart
@@ -51,6 +51,8 @@
static const String endNamedGroupString = _rightBraceString;
static const int nameSeparator = _colon;
static const String nameSeparatorString = _colonString;
+ static const int requiredNameSeparator = _exclamation;
+ static const String requiredNameSeparatorString = _exclamationString;
static const int genericFunctionTypeParameterIndex = _circumflex;
static const String genericFunctionTypeParameterIndexString =
@@ -189,6 +191,8 @@
test("startNamedGroup", startNamedGroup, startNamedGroupString);
test("endNamedGroup", endNamedGroup, endNamedGroupString);
test("nameSeparator", nameSeparator, nameSeparatorString);
+ test("requiredNameSeparator", requiredNameSeparator,
+ requiredNameSeparatorString);
test("genericFunctionTypeParameterIndex", genericFunctionTypeParameterIndex,
genericFunctionTypeParameterIndexString);
test("extensionOp", extensionOp, extensionOpString);
diff --git a/sdk_nnbd/lib/_internal/vm/bin/builtin.dart b/sdk_nnbd/lib/_internal/vm/bin/builtin.dart
index 1befe5a..711abb0 100644
--- a/sdk_nnbd/lib/_internal/vm/bin/builtin.dart
+++ b/sdk_nnbd/lib/_internal/vm/bin/builtin.dart
@@ -9,6 +9,7 @@
import 'dart:collection' hide LinkedList, LinkedListEntry;
import 'dart:_internal' hide Symbol;
import 'dart:io';
+import 'dart:convert';
import 'dart:isolate';
import 'dart:typed_data';
@@ -430,9 +431,67 @@
return result;
}
+_loadPackageConfigFile(bool traceLoading, Uri packageConfig) {
+ try {
+ final Uint8List data = File.fromUri(packageConfig).readAsBytesSync();
+ if (traceLoading) {
+ _log("Loaded package config file from $packageConfig.");
+ }
+ return _parsePackageConfig(traceLoading, packageConfig, data);
+ } catch (e, s) {
+ if (traceLoading) {
+ _log("Error loading packages: $e\n$s");
+ }
+ return "Uncaught error ($e) loading packages file.";
+ }
+}
+
+// The .dart_tool/package_config.json format is described in
+//
+// https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/package-config-file-v2.md
+//
+// The returned list has the format:
+//
+// [0] Location of package_config.json file.
+// [1] null
+// [n*2] Name of n-th package
+// [n*2 + 1] Location of n-th package's sources (as a String)
+//
+List _parsePackageConfig(
+ bool traceLoading, Uri packageConfig, Uint8List bytes) {
+ final Map packageJson = json.decode(utf8.decode(bytes));
+ final version = packageJson['configVersion'];
+ if (version != 2) {
+ throw 'The package configuration file has an unsupported version.';
+ }
+ // The first entry contains the location of the identified
+ // .dart_tool/package_config.json file instead of a mapping.
+ final result = <dynamic>[packageConfig.toString(), null];
+ final List packages = packageJson['packages'] ?? [];
+ for (final Map package in packages) {
+ final String name = package['name'];
+ final String rootUri = package['rootUri'];
+ final String? packageUri = package['packageUri'];
+ final Uri resolvedRootUri = packageConfig.resolve(rootUri);
+ final Uri resolvedPackageUri = packageUri != null
+ ? resolvedRootUri.resolve(packageUri)
+ : resolvedRootUri;
+ if (packageUri != null &&
+ !'$resolvedPackageUri'.contains('$resolvedRootUri')) {
+ throw 'The resolved "packageUri" is not a subdirectory of the "rootUri".';
+ }
+ result.add(name);
+ result.add(resolvedPackageUri.toString());
+ if (traceLoading) {
+ _log('Resolved package $name to be at $resolvedPackageUri');
+ }
+ }
+ return result;
+}
+
_loadPackagesFile(bool traceLoading, Uri packagesFile) {
try {
- var data = new File.fromUri(packagesFile).readAsBytesSync();
+ final Uint8List data = File.fromUri(packagesFile).readAsBytesSync();
if (traceLoading) {
_log("Loaded packages file from $packagesFile:\n"
"${new String.fromCharCodes(data)}");
@@ -446,39 +505,49 @@
}
}
-_findPackagesFile(bool traceLoading, Uri base) {
+_findPackagesConfiguration(bool traceLoading, Uri base) {
try {
- // Walk up the directory hierarchy to check for the existence of
- // .packages files in parent directories and for the existence of a
- // packages/ directory on the first iteration.
- var dir = new File.fromUri(base).parent;
- var prev = null;
- // Keep searching until we reach the root.
- while ((prev == null) || (prev.path != dir.path)) {
- // Check for the existence of a .packages file and if it exists try to
- // load and parse it.
- var dirUri = dir.uri;
- var packagesFile = dirUri.resolve(".packages");
+ // Walk up the directory hierarchy to check for the existence of either one
+ // of
+ // - .dart_tool/package_config.json
+ // - .packages
+ var currentDir = new File.fromUri(base).parent;
+ while (true) {
+ final dirUri = currentDir.uri;
+
+ // We prefer using `.dart_tool/package_config.json` over `.packages`.
+ final packageConfig = dirUri.resolve(".dart_tool/package_config.json");
+ if (traceLoading) {
+ _log("Checking for $packageConfig file.");
+ }
+ bool exists = File.fromUri(packageConfig).existsSync();
+ if (traceLoading) {
+ _log("$packageConfig exists: $exists");
+ }
+ if (exists) {
+ return _loadPackageConfigFile(traceLoading, packageConfig);
+ }
+
+ final packagesFile = dirUri.resolve(".packages");
if (traceLoading) {
_log("Checking for $packagesFile file.");
}
- var exists = new File.fromUri(packagesFile).existsSync();
+ exists = File.fromUri(packagesFile).existsSync();
if (traceLoading) {
_log("$packagesFile exists: $exists");
}
if (exists) {
return _loadPackagesFile(traceLoading, packagesFile);
}
- // Move up one level.
- prev = dir;
- dir = dir.parent;
+ final parentDir = currentDir.parent;
+ if (dirUri == parentDir.uri) break;
+ currentDir = parentDir;
}
- // No .packages file was found.
if (traceLoading) {
- _log("Could not resolve a package location from $base");
+ _log("Could not resolve a package configuration from $base");
}
- return "Could not resolve a package location for base at $base";
+ return "Could not resolve a package configuration for base at $base";
} catch (e, s) {
if (traceLoading) {
_log("Error loading packages: $e\n$s");
@@ -509,7 +578,7 @@
try {
if (tag == -1) {
if (resource.scheme == '' || resource.scheme == 'file') {
- return _findPackagesFile(traceLoading, resource);
+ return _findPackagesConfiguration(traceLoading, resource);
} else {
return "Unsupported scheme used to locate .packages file:'$resource'.";
}
@@ -580,6 +649,9 @@
}
// Embedder Entrypoint:
+// The embedder calls this method with the value of the --packages command line
+// option. It can point to a ".packages" or a ".dart_tool/package_config.json"
+// file.
@pragma("vm:entry-point")
String _setPackagesMap(String packagesParam) {
if (!_setupCompleted) {
diff --git a/sdk_nnbd/lib/_internal/vm/bin/common_patch.dart b/sdk_nnbd/lib/_internal/vm/bin/common_patch.dart
index 1bcd089..02a9df7 100644
--- a/sdk_nnbd/lib/_internal/vm/bin/common_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/bin/common_patch.dart
@@ -7,7 +7,7 @@
/// patches of that library. We plan to change this when we have a shared front
/// end and simply use parts.
-import "dart:_internal" show VMLibraryHooks, patch;
+import "dart:_internal" show VMLibraryHooks, patch, checkNotNullable;
import "dart:async"
show
diff --git a/sdk_nnbd/lib/_internal/vm/bin/socket_patch.dart b/sdk_nnbd/lib/_internal/vm/bin/socket_patch.dart
index b5ea987..94072d8 100644
--- a/sdk_nnbd/lib/_internal/vm/bin/socket_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/bin/socket_patch.dart
@@ -89,6 +89,11 @@
InternetAddress address, String host) {
return (address as _InternetAddress)._cloneWithNewHost(host);
}
+
+ @patch
+ static InternetAddress? tryParse(String address) {
+ return _InternetAddress.tryParse(address);
+ }
}
@patch
@@ -255,6 +260,16 @@
}
}
+ static _InternetAddress? tryParse(String address) {
+ checkNotNullable(address, "address");
+ var addressBytes = _parse(address);
+ if (addressBytes == null) return null;
+ var type = addressBytes.length == _IPv4AddrLength
+ ? InternetAddressType.IPv4
+ : InternetAddressType.IPv6;
+ return _InternetAddress(type, address, null, addressBytes);
+ }
+
factory _InternetAddress.fixed(int id) {
switch (id) {
case _addressLoopbackIPv4:
diff --git a/sdk_nnbd/lib/_internal/vm/lib/internal_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/internal_patch.dart
index b484a2c..2faf799 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/internal_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/internal_patch.dart
@@ -52,7 +52,6 @@
// Implementation of package root/map provision.
static var packageRootString;
static var packageConfigString;
- static var packageRootUriFuture;
static var packageConfigUriFuture;
static var resolvePackageUriFuture;
diff --git a/sdk_nnbd/lib/_internal/vm/lib/isolate_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/isolate_patch.dart
index 77e3844..7658010 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/isolate_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/isolate_patch.dart
@@ -272,7 +272,7 @@
// current isolate's control port and capabilities.
//
// TODO(floitsch): Send an error message if we can't find the entry point.
- var readyMessage = new List<Object?>.filled(2, null);
+ final readyMessage = List<Object?>.filled(2, null);
readyMessage[0] = controlPort.sendPort;
readyMessage[1] = capabilities;
@@ -342,7 +342,6 @@
}
static bool _packageSupported() =>
- (VMLibraryHooks.packageRootUriFuture != null) &&
(VMLibraryHooks.packageConfigUriFuture != null) &&
(VMLibraryHooks.resolvePackageUriFuture != null);
@@ -376,18 +375,8 @@
final RawReceivePort readyPort = new RawReceivePort();
try {
- _spawnFunction(
- readyPort.sendPort,
- script.toString(),
- entryPoint,
- message,
- paused,
- errorsAreFatal,
- onExit,
- onError,
- null,
- packageConfig,
- debugName);
+ _spawnFunction(readyPort.sendPort, script.toString(), entryPoint, message,
+ paused, errorsAreFatal, onExit, onError, packageConfig, debugName);
return await _spawnCommon(readyPort);
} catch (e, st) {
readyPort.close();
@@ -430,24 +419,17 @@
}
}
// Resolve the uri against the current isolate's root Uri first.
- var spawnedUri = _rootUri!.resolveUri(uri);
+ final Uri spawnedUri = _rootUri!.resolveUri(uri);
// Inherit this isolate's package resolution setup if not overridden.
- if (!automaticPackageResolution &&
- (packageRoot == null) &&
- (packageConfig == null)) {
+ if (!automaticPackageResolution && packageConfig == null) {
if (Isolate._packageSupported()) {
- packageRoot = await Isolate.packageRoot;
packageConfig = await Isolate.packageConfig;
}
}
// Ensure to resolve package: URIs being handed in as parameters.
- if (packageRoot != null) {
- // `packages/` directory is no longer supported. Force it null.
- // TODO(mfairhurst) Should this throw an exception?
- packageRoot = null;
- } else if (packageConfig != null) {
+ if (packageConfig != null) {
// Avoid calling resolvePackageUri if not strictly necessary in case
// the API is not supported.
if (packageConfig.isScheme("package")) {
@@ -456,8 +438,7 @@
}
// The VM will invoke [_startIsolate] and not `main`.
- var packageRootString = packageRoot?.toString();
- var packageConfigString = packageConfig?.toString();
+ final packageConfigString = packageConfig?.toString();
final RawReceivePort readyPort = new RawReceivePort();
try {
@@ -473,7 +454,6 @@
checked,
null,
/* environment */
- packageRootString,
packageConfigString,
debugName);
return await _spawnCommon(readyPort);
@@ -529,7 +509,6 @@
bool errorsAreFatal,
SendPort? onExit,
SendPort? onError,
- String? packageRoot,
String? packageConfig,
String? debugName) native "Isolate_spawnFunction";
@@ -544,7 +523,6 @@
bool errorsAreFatal,
bool? checked,
List? environment,
- String? packageRoot,
String? packageConfig,
String? debugName) native "Isolate_spawnUri";
diff --git a/sdk_nnbd/lib/html/dart2js/html_dart2js.dart b/sdk_nnbd/lib/html/dart2js/html_dart2js.dart
index 7330bc6..0a6e37b 100644
--- a/sdk_nnbd/lib/html/dart2js/html_dart2js.dart
+++ b/sdk_nnbd/lib/html/dart2js/html_dart2js.dart
@@ -10448,13 +10448,13 @@
implements NonElementParentNode, ParentNode {
factory DocumentFragment() => document.createDocumentFragment();
- factory DocumentFragment.html(String html,
+ factory DocumentFragment.html(String? html,
{NodeValidator? validator, NodeTreeSanitizer? treeSanitizer}) {
return document.body!.createFragment(html,
validator: validator, treeSanitizer: treeSanitizer);
}
- factory DocumentFragment.svg(String svgContent,
+ factory DocumentFragment.svg(String? svgContent,
{NodeValidator? validator, NodeTreeSanitizer? treeSanitizer}) {
return new svg.SvgSvgElement().createFragment(svgContent,
validator: validator, treeSanitizer: treeSanitizer);
@@ -10503,11 +10503,11 @@
return e.innerHtml;
}
- set innerHtml(String value) {
+ set innerHtml(String? value) {
this.setInnerHtml(value);
}
- void setInnerHtml(String html,
+ void setInnerHtml(String? html,
{NodeValidator? validator, NodeTreeSanitizer? treeSanitizer}) {
this.nodes.clear();
append(document.body!.createFragment(html,
@@ -12664,7 +12664,7 @@
* * [NodeValidator]
*
*/
- factory Element.html(String html,
+ factory Element.html(String? html,
{NodeValidator? validator, NodeTreeSanitizer? treeSanitizer}) {
var fragment = document.body!.createFragment(html,
validator: validator, treeSanitizer: treeSanitizer);
@@ -13626,7 +13626,7 @@
* * [NodeValidator]
* * [NodeTreeSanitizer]
*/
- DocumentFragment createFragment(String html,
+ DocumentFragment createFragment(String? html,
{NodeValidator? validator, NodeTreeSanitizer? treeSanitizer}) {
if (treeSanitizer == null) {
if (validator == null) {
@@ -13674,7 +13674,7 @@
if (Range.supportsCreateContextualFragment &&
_canBeUsedToCreateContextualFragment) {
_parseRange!.selectNodeContents(contextElement);
- fragment = _parseRange!.createContextualFragment(html);
+ fragment = _parseRange!.createContextualFragment(html!);
} else {
contextElement._innerHtml = html;
@@ -13768,7 +13768,7 @@
if (treeSanitizer is _TrustedHtmlTreeSanitizer) {
_innerHtml = html;
} else {
- append(createFragment(html!,
+ append(createFragment(html,
validator: validator, treeSanitizer: treeSanitizer));
}
}
@@ -29332,7 +29332,7 @@
@JSName('createTBody')
TableSectionElement _nativeCreateTBody() native;
- DocumentFragment createFragment(String html,
+ DocumentFragment createFragment(String? html,
{NodeValidator? validator, NodeTreeSanitizer? treeSanitizer}) {
if (Range.supportsCreateContextualFragment) {
return super.createFragment(html,
@@ -29423,7 +29423,7 @@
TableCellElement insertCell(int index) =>
_insertCell(index) as TableCellElement;
- DocumentFragment createFragment(String html,
+ DocumentFragment createFragment(String? html,
{NodeValidator? validator, NodeTreeSanitizer? treeSanitizer}) {
if (Range.supportsCreateContextualFragment) {
return super.createFragment(html,
@@ -29486,7 +29486,7 @@
TableRowElement insertRow(int index) => _insertRow(index) as TableRowElement;
- DocumentFragment createFragment(String html,
+ DocumentFragment createFragment(String? html,
{NodeValidator? validator, NodeTreeSanitizer? treeSanitizer}) {
if (Range.supportsCreateContextualFragment) {
return super.createFragment(html,
@@ -29585,7 +29585,7 @@
{NodeValidator? validator, NodeTreeSanitizer? treeSanitizer}) {
text = null;
content.nodes.clear();
- var fragment = createFragment(html!,
+ var fragment = createFragment(html,
validator: validator, treeSanitizer: treeSanitizer);
content.append(fragment);
@@ -40391,7 +40391,7 @@
view = window;
}
- var eventObj;
+ dynamic eventObj;
// Currently this works on everything but Safari. Safari throws an
// "Attempting to change access mechanism for an unconfigurable property"
diff --git a/sdk_nnbd/lib/io/socket.dart b/sdk_nnbd/lib/io/socket.dart
index bf1e209..b5e814f 100644
--- a/sdk_nnbd/lib/io/socket.dart
+++ b/sdk_nnbd/lib/io/socket.dart
@@ -213,6 +213,12 @@
*/
external static InternetAddress _cloneWithNewHost(
InternetAddress address, String host);
+
+ /// Attempts to parse [address] as a numeric address.
+ ///
+ /// Returns `null` If [address] is not a numeric IPv4 (dotted-decimal
+ /// notation) or IPv6 (hexadecimal representation) address.
+ external static InternetAddress? tryParse(String address);
}
/**
diff --git a/sdk_nnbd/lib/svg/dart2js/svg_dart2js.dart b/sdk_nnbd/lib/svg/dart2js/svg_dart2js.dart
index 3e319cd..0ca84b9 100644
--- a/sdk_nnbd/lib/svg/dart2js/svg_dart2js.dart
+++ b/sdk_nnbd/lib/svg/dart2js/svg_dart2js.dart
@@ -3041,7 +3041,7 @@
this.setInnerHtml(value);
}
- DocumentFragment createFragment(String svg,
+ DocumentFragment createFragment(String? svg,
{NodeValidator? validator, NodeTreeSanitizer? treeSanitizer}) {
if (treeSanitizer == null) {
if (validator == null) {
diff --git a/sdk_nnbd/lib/vmservice/running_isolate.dart b/sdk_nnbd/lib/vmservice/running_isolate.dart
index 9de347f..029c6aa 100644
--- a/sdk_nnbd/lib/vmservice/running_isolate.dart
+++ b/sdk_nnbd/lib/vmservice/running_isolate.dart
@@ -105,7 +105,7 @@
var pauseType;
try {
pauseType = await _isolatePauseType(service, message.params['isolateId']);
- } catch (errorResponse) {
+ } on Response catch (errorResponse) {
return errorResponse;
}
if (pauseType == kInvalidPauseEvent ||
diff --git a/tests/co19/co19-co19.status b/tests/co19/co19-co19.status
new file mode 100644
index 0000000..14f2c45
--- /dev/null
+++ b/tests/co19/co19-co19.status
@@ -0,0 +1,642 @@
+# Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+Language/Classes/*: Skip # Not migrated to NNBD
+Language/Classes/Abstract_Instance_Members/*: Skip # Not migrated to NNBD
+Language/Classes/Class_Member_Conflicts/*: Skip # Not migrated to NNBD
+Language/Classes/Constructors/*: Skip # Not migrated to NNBD
+Language/Classes/Constructors/Constant_Constructors/*: Skip # Not migrated to NNBD
+Language/Classes/Constructors/Factories/*: Skip # Not migrated to NNBD
+Language/Classes/Constructors/Generative_Constructors/*: Skip # Not migrated to NNBD
+Language/Classes/Getters/*: Skip # Not migrated to NNBD
+Language/Classes/Instance_Methods/*: Skip # Not migrated to NNBD
+Language/Classes/Instance_Methods/Operators/*: Skip # Not migrated to NNBD
+Language/Classes/Instance_Variables/*: Skip # Not migrated to NNBD
+Language/Classes/Setters/*: Skip # Not migrated to NNBD
+Language/Classes/Static_Methods/*: Skip # Not migrated to NNBD
+Language/Classes/Static_Variables/*: Skip # Not migrated to NNBD
+Language/Classes/Superclasses/*: Skip # Not migrated to NNBD
+Language/Classes/Superclasses/Inheritance_and_Overriding/*: Skip # Not migrated to NNBD
+Language/Classes/Superinterfaces/*: Skip # Not migrated to NNBD
+Language/Enums/*: Skip # Not migrated to NNBD
+Language/Errors_and_Warnings/*: Skip # Not migrated to NNBD
+Language/Expressions/*: Skip # Not migrated to NNBD
+Language/Expressions/Additive_Expressions/*: Skip # Not migrated to NNBD
+Language/Expressions/Assignable_Expressions/*: Skip # Not migrated to NNBD
+Language/Expressions/Assignment/*: Skip # Not migrated to NNBD
+Language/Expressions/Assignment/Compound_Assignment/*: Skip # Not migrated to NNBD
+Language/Expressions/Await_Expressions/*: Skip # Not migrated to NNBD
+Language/Expressions/Bitwise_Expressions/*: Skip # Not migrated to NNBD
+Language/Expressions/Booleans/*: Skip # Not migrated to NNBD
+Language/Expressions/Booleans/Boolean_Conversion/*: Skip # Not migrated to NNBD
+Language/Expressions/Conditional/*: Skip # Not migrated to NNBD
+Language/Expressions/Constants/*: Skip # Not migrated to NNBD
+Language/Expressions/Equality/*: Skip # Not migrated to NNBD
+Language/Expressions/Function_Expressions/*: Skip # Not migrated to NNBD
+Language/Expressions/Function_Invocation/*: Skip # Not migrated to NNBD
+Language/Expressions/Function_Invocation/Actual_Argument_List_Evaluation/*: Skip # Not migrated to NNBD
+Language/Expressions/Function_Invocation/Binding_Actuals_to_Formals/*: Skip # Not migrated to NNBD
+Language/Expressions/Function_Invocation/Function_Expression_Invocation/*: Skip # Not migrated to NNBD
+Language/Expressions/Function_Invocation/Unqualified_Invocation/*: Skip # Not migrated to NNBD
+Language/Expressions/Identifier_Reference/*: Skip # Not migrated to NNBD
+Language/Expressions/If_null_Expressions/*: Skip # Not migrated to NNBD
+Language/Expressions/Instance_Creation/*: Skip # Not migrated to NNBD
+Language/Expressions/Instance_Creation/Const/*: Skip # Not migrated to NNBD
+Language/Expressions/Instance_Creation/New/*: Skip # Not migrated to NNBD
+Language/Expressions/Lists/*: Skip # Not migrated to NNBD
+Language/Expressions/Logical_Boolean_Expressions/*: Skip # Not migrated to NNBD
+Language/Expressions/Lookup/*: Skip # Not migrated to NNBD
+Language/Expressions/Lookup/Getter_and_Setter_Lookup/*: Skip # Not migrated to NNBD
+Language/Expressions/Lookup/Method_Lookup/*: Skip # Not migrated to NNBD
+Language/Expressions/Maps/*: Skip # Not migrated to NNBD
+Language/Expressions/Method_Invocation/*: Skip # Not migrated to NNBD
+Language/Expressions/Method_Invocation/Cascaded_Invocations/*: Skip # Not migrated to NNBD
+Language/Expressions/Method_Invocation/Ordinary_Invocation/*: Skip # Not migrated to NNBD
+Language/Expressions/Method_Invocation/Super_Invocation/*: Skip # Not migrated to NNBD
+Language/Expressions/Multiplicative_Expressions/*: Skip # Not migrated to NNBD
+Language/Expressions/Null/*: Skip # Not migrated to NNBD
+Language/Expressions/Numbers/*: Skip # Not migrated to NNBD
+Language/Expressions/Object_Identity/*: Skip # Not migrated to NNBD
+Language/Expressions/Postfix_Expressions/*: Skip # Not migrated to NNBD
+Language/Expressions/Property_Extraction/*: Skip # Not migrated to NNBD
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/*: Skip # Not migrated to NNBD
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/*: Skip # Not migrated to NNBD
+Language/Expressions/Property_Extraction/Super_Closurization/*: Skip # Not migrated to NNBD
+Language/Expressions/Property_Extraction/Super_Getter_Access_and_Method_Closurization/*: Skip # Not migrated to NNBD
+Language/Expressions/Relational_Expressions/*: Skip # Not migrated to NNBD
+Language/Expressions/Shift/*: Skip # Not migrated to NNBD
+Language/Expressions/Spawning_an_Isolate/*: Skip # Not migrated to NNBD
+Language/Expressions/Strings/*: Skip # Not migrated to NNBD
+Language/Expressions/Strings/String_Interpolation/*: Skip # Not migrated to NNBD
+Language/Expressions/Symbols/*: Skip # Not migrated to NNBD
+Language/Expressions/This/*: Skip # Not migrated to NNBD
+Language/Expressions/Throw/*: Skip # Not migrated to NNBD
+Language/Expressions/Top_level_Getter_Invocation/*: Skip # Not migrated to NNBD
+Language/Expressions/Type_Cast/*: Skip # Not migrated to NNBD
+Language/Expressions/Type_Test/*: Skip # Not migrated to NNBD
+Language/Expressions/Unary_Expressions/*: Skip # Not migrated to NNBD
+Language/Functions/*: Skip # Not migrated to NNBD
+Language/Functions/External_Functions/*: Skip # Not migrated to NNBD
+Language/Functions/Formal_Parameters/*: Skip # Not migrated to NNBD
+Language/Functions/Formal_Parameters/Optional_Formals/*: Skip # Not migrated to NNBD
+Language/Functions/Formal_Parameters/Required_Formals/*: Skip # Not migrated to NNBD
+Language/Functions/Function_Declarations/*: Skip # Not migrated to NNBD
+Language/Functions/Type_of_a_Function/*: Skip # Not migrated to NNBD
+Language/Generics/*: Skip # Not migrated to NNBD
+Language/Generics/Superbounded_types/*: Skip # Not migrated to NNBD
+Language/Interfaces/Superinterfaces/*: Skip # Not migrated to NNBD
+Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/*: Skip # Not migrated to NNBD
+Language/Libraries_and_Scripts/*: Skip # Not migrated to NNBD
+Language/Libraries_and_Scripts/Exports/*: Skip # Not migrated to NNBD
+Language/Libraries_and_Scripts/Imports/*: Skip # Not migrated to NNBD
+Language/Libraries_and_Scripts/Parts/*: Skip # Not migrated to NNBD
+Language/Libraries_and_Scripts/Scripts/*: Skip # Not migrated to NNBD
+Language/Libraries_and_Scripts/URIs/*: Skip # Not migrated to NNBD
+Language/Metadata/*: Skip # Not migrated to NNBD
+Language/Mixins/*: Skip # Not migrated to NNBD
+Language/Mixins/Mixin_Application/*: Skip # Not migrated to NNBD
+Language/Mixins/Mixin_Composition/*: Skip # Not migrated to NNBD
+Language/Overview/*: Skip # Not migrated to NNBD
+Language/Overview/Privacy/*: Skip # Not migrated to NNBD
+Language/Overview/Scoping/*: Skip # Not migrated to NNBD
+Language/Reference/Lexical_Rules/*: Skip # Not migrated to NNBD
+Language/Reference/Lexical_Rules/Comments/*: Skip # Not migrated to NNBD
+Language/Reference/Lexical_Rules/Reserved_Words/*: Skip # Not migrated to NNBD
+Language/Reference/Operator_Precedence/*: Skip # Not migrated to NNBD
+Language/Statements/Assert/*: Skip # Not migrated to NNBD
+Language/Statements/Blocks/*: Skip # Not migrated to NNBD
+Language/Statements/Break/*: Skip # Not migrated to NNBD
+Language/Statements/Continue/*: Skip # Not migrated to NNBD
+Language/Statements/Do/*: Skip # Not migrated to NNBD
+Language/Statements/Expression_Statements/*: Skip # Not migrated to NNBD
+Language/Statements/For/*: Skip # Not migrated to NNBD
+Language/Statements/For/Asynchronous_For_in/*: Skip # Not migrated to NNBD
+Language/Statements/For/For_Loop/*: Skip # Not migrated to NNBD
+Language/Statements/For/For_in/*: Skip # Not migrated to NNBD
+Language/Statements/If/*: Skip # Not migrated to NNBD
+Language/Statements/Labels/*: Skip # Not migrated to NNBD
+Language/Statements/Local_Function_Declaration/*: Skip # Not migrated to NNBD
+Language/Statements/Local_Variable_Declaration/*: Skip # Not migrated to NNBD
+Language/Statements/Rethrow/*: Skip # Not migrated to NNBD
+Language/Statements/Return/*: Skip # Not migrated to NNBD
+Language/Statements/Switch/*: Skip # Not migrated to NNBD
+Language/Statements/Try/*: Skip # Not migrated to NNBD
+Language/Statements/While/*: Skip # Not migrated to NNBD
+Language/Statements/Yield_and_Yield_Each/*: Skip # Not migrated to NNBD
+Language/Statements/Yield_and_Yield_Each/Yield/*: Skip # Not migrated to NNBD
+Language/Statements/Yield_and_Yield_Each/Yield_Each/*: Skip # Not migrated to NNBD
+Language/Types/Dynamic_Type_System/*: Skip # Not migrated to NNBD
+Language/Types/Function_Types/*: Skip # Not migrated to NNBD
+Language/Types/Interface_Types/*: Skip # Not migrated to NNBD
+Language/Types/Parameterized_Types/*: Skip # Not migrated to NNBD
+Language/Types/Parameterized_Types/Actual_Type_of_Declaration/*: Skip # Not migrated to NNBD
+Language/Types/Static_Types/*: Skip # Not migrated to NNBD
+Language/Types/Type_Aliases/*: Skip # Not migrated to NNBD
+Language/Types/Type_Void/*: Skip # Not migrated to NNBD
+Language/Types/Type_dynamic/*: Skip # Not migrated to NNBD
+Language/Variables/*: Skip # Not migrated to NNBD
+Language/Variables/Evaluation_of_Implicit_Variable_Getters/*: Skip # Not migrated to NNBD
+LanguageFeatures/Constant-update-2018/*: Skip # Not migrated to NNBD
+LanguageFeatures/Control-flow-collections/*: Skip # Not migrated to NNBD
+LanguageFeatures/Extension-methods/*: Skip # Not migrated to NNBD
+LanguageFeatures/Instantiate-to-bound/*: Skip # Not migrated to NNBD
+LanguageFeatures/Instantiate-to-bound/class/*: Skip # Not migrated to NNBD
+LanguageFeatures/Instantiate-to-bound/class/dynamic/*: Skip # Not migrated to NNBD
+LanguageFeatures/Instantiate-to-bound/class/static/*: Skip # Not migrated to NNBD
+LanguageFeatures/Instantiate-to-bound/nonfunction_typedef/*: Skip # Not migrated to NNBD
+LanguageFeatures/Instantiate-to-bound/nonfunction_typedef/dynamic/*: Skip # Not migrated to NNBD
+LanguageFeatures/Instantiate-to-bound/nonfunction_typedef/static/*: Skip # Not migrated to NNBD
+LanguageFeatures/Instantiate-to-bound/typedef/*: Skip # Not migrated to NNBD
+LanguageFeatures/Instantiate-to-bound/typedef/dynamic/*: Skip # Not migrated to NNBD
+LanguageFeatures/Instantiate-to-bound/typedef/static/*: Skip # Not migrated to NNBD
+LanguageFeatures/Set-literals/*: Skip # Not migrated to NNBD
+LanguageFeatures/Simple-bounds/*: Skip # Not migrated to NNBD
+LanguageFeatures/Simple-bounds/dynamic/*: Skip # Not migrated to NNBD
+LanguageFeatures/Simple-bounds/dynamic/type-aliases/*: Skip # Not migrated to NNBD
+LanguageFeatures/Simple-bounds/static/*: Skip # Not migrated to NNBD
+LanguageFeatures/Simple-bounds/static/type-aliases/*: Skip # Not migrated to NNBD
+LanguageFeatures/Spread-collections/*: Skip # Not migrated to NNBD
+LanguageFeatures/Super-bounded-types/*: Skip # Not migrated to NNBD
+LanguageFeatures/Super-mixins/*: Skip # Not migrated to NNBD
+LanguageFeatures/Triple-Shift/*: Skip # Not migrated to NNBD
+LanguageFeatures/int-to-double/*: Skip # Not migrated to NNBD
+LanguageFeatures/regression/*: Skip # Not migrated to NNBD
+LibTest/async/Completer/*: Skip # Not migrated to NNBD
+LibTest/async/DeferredLibrary/*: Skip # Not migrated to NNBD
+LibTest/async/EventSink/*: Skip # Not migrated to NNBD
+LibTest/async/Future/*: Skip # Not migrated to NNBD
+LibTest/async/Stream/*: Skip # Not migrated to NNBD
+LibTest/async/StreamConsumer/*: Skip # Not migrated to NNBD
+LibTest/async/StreamController/*: Skip # Not migrated to NNBD
+LibTest/async/StreamIterator/*: Skip # Not migrated to NNBD
+LibTest/async/StreamSink/*: Skip # Not migrated to NNBD
+LibTest/async/StreamTransformer/*: Skip # Not migrated to NNBD
+LibTest/async/Timer/*: Skip # Not migrated to NNBD
+LibTest/async/Zone/*: Skip # Not migrated to NNBD
+LibTest/collection/DoubleLinkedQueue/*: Skip # Not migrated to NNBD
+LibTest/collection/DoubleLinkedQueueEntry/*: Skip # Not migrated to NNBD
+LibTest/collection/HasNextIterator/*: Skip # Not migrated to NNBD
+LibTest/collection/HashMap/*: Skip # Not migrated to NNBD
+LibTest/collection/HashSet/*: Skip # Not migrated to NNBD
+LibTest/collection/IterableBase/*: Skip # Not migrated to NNBD
+LibTest/collection/IterableMixin/*: Skip # Not migrated to NNBD
+LibTest/collection/LinkedHashMap/*: Skip # Not migrated to NNBD
+LibTest/collection/LinkedHashSet/*: Skip # Not migrated to NNBD
+LibTest/collection/LinkedList/*: Skip # Not migrated to NNBD
+LibTest/collection/LinkedListEntry/*: Skip # Not migrated to NNBD
+LibTest/collection/ListBase/*: Skip # Not migrated to NNBD
+LibTest/collection/ListMixin/*: Skip # Not migrated to NNBD
+LibTest/collection/ListQueue/*: Skip # Not migrated to NNBD
+LibTest/collection/MapBase/*: Skip # Not migrated to NNBD
+LibTest/collection/MapMixin/*: Skip # Not migrated to NNBD
+LibTest/collection/MapView/*: Skip # Not migrated to NNBD
+LibTest/collection/Queue/*: Skip # Not migrated to NNBD
+LibTest/collection/SetBase/*: Skip # Not migrated to NNBD
+LibTest/collection/SetMixin/*: Skip # Not migrated to NNBD
+LibTest/collection/SplayTreeMap/*: Skip # Not migrated to NNBD
+LibTest/collection/SplayTreeSet/*: Skip # Not migrated to NNBD
+LibTest/collection/UnmodifiableListView/*: Skip # Not migrated to NNBD
+LibTest/collection/UnmodifiableMapBase/*: Skip # Not migrated to NNBD
+LibTest/collection/UnmodifiableMapView/*: Skip # Not migrated to NNBD
+LibTest/convert/AsciiCodec/*: Skip # Not migrated to NNBD
+LibTest/convert/AsciiDecoder/*: Skip # Not migrated to NNBD
+LibTest/convert/AsciiEncoder/*: Skip # Not migrated to NNBD
+LibTest/convert/Base64Codec/*: Skip # Not migrated to NNBD
+LibTest/convert/Base64Decoder/*: Skip # Not migrated to NNBD
+LibTest/convert/Base64Encoder/*: Skip # Not migrated to NNBD
+LibTest/convert/ByteConversionSink/*: Skip # Not migrated to NNBD
+LibTest/convert/ChunkedConversionSink/*: Skip # Not migrated to NNBD
+LibTest/convert/ClosableStringSink/*: Skip # Not migrated to NNBD
+LibTest/convert/Encoding/*: Skip # Not migrated to NNBD
+LibTest/convert/HtmlEscape/*: Skip # Not migrated to NNBD
+LibTest/convert/HtmlEscapeMode/*: Skip # Not migrated to NNBD
+LibTest/convert/JsonCodec/*: Skip # Not migrated to NNBD
+LibTest/convert/JsonDecoder/*: Skip # Not migrated to NNBD
+LibTest/convert/JsonEncoder/*: Skip # Not migrated to NNBD
+LibTest/convert/JsonUtf8Encoder/*: Skip # Not migrated to NNBD
+LibTest/convert/Latin1Codec/*: Skip # Not migrated to NNBD
+LibTest/convert/Latin1Decoder/*: Skip # Not migrated to NNBD
+LibTest/convert/Latin1Encoder/*: Skip # Not migrated to NNBD
+LibTest/convert/LineSplitter/*: Skip # Not migrated to NNBD
+LibTest/convert/StringConversionSink/*: Skip # Not migrated to NNBD
+LibTest/convert/Utf8Codec/*: Skip # Not migrated to NNBD
+LibTest/convert/Utf8Decoder/*: Skip # Not migrated to NNBD
+LibTest/convert/Utf8Encoder/*: Skip # Not migrated to NNBD
+LibTest/core/AbstractClassInstantiationError/*: Skip # Not migrated to NNBD
+LibTest/core/ArgumentError/*: Skip # Not migrated to NNBD
+LibTest/core/AssertionError/*: Skip # Not migrated to NNBD
+LibTest/core/BidirectionalIterator/*: Skip # Not migrated to NNBD
+LibTest/core/CastError/*: Skip # Not migrated to NNBD
+LibTest/core/ConcurrentModificationError/*: Skip # Not migrated to NNBD
+LibTest/core/CyclicInitializationError/*: Skip # Not migrated to NNBD
+LibTest/core/DateTime/*: Skip # Not migrated to NNBD
+LibTest/core/Deprecated/*: Skip # Not migrated to NNBD
+LibTest/core/Duration/*: Skip # Not migrated to NNBD
+LibTest/core/Error/*: Skip # Not migrated to NNBD
+LibTest/core/Exception/*: Skip # Not migrated to NNBD
+LibTest/core/Expando/*: Skip # Not migrated to NNBD
+LibTest/core/FallThroughError/*: Skip # Not migrated to NNBD
+LibTest/core/FormatException/*: Skip # Not migrated to NNBD
+LibTest/core/Function/*: Skip # Not migrated to NNBD
+LibTest/core/IndexError/*: Skip # Not migrated to NNBD
+LibTest/core/IntegerDivisionByZeroException/*: Skip # Not migrated to NNBD
+LibTest/core/Invocation/*: Skip # Not migrated to NNBD
+LibTest/core/Iterable/*: Skip # Not migrated to NNBD
+LibTest/core/Iterator/*: Skip # Not migrated to NNBD
+LibTest/core/List/*: Skip # Not migrated to NNBD
+LibTest/core/Map/*: Skip # Not migrated to NNBD
+LibTest/core/Match/*: Skip # Not migrated to NNBD
+LibTest/core/NoSuchMethodError/*: Skip # Not migrated to NNBD
+LibTest/core/Null/*: Skip # Not migrated to NNBD
+LibTest/core/Object/*: Skip # Not migrated to NNBD
+LibTest/core/OutOfMemoryError/*: Skip # Not migrated to NNBD
+LibTest/core/RangeError/*: Skip # Not migrated to NNBD
+LibTest/core/RegExp/*: Skip # Not migrated to NNBD
+LibTest/core/RegExp/Pattern_semantics/*: Skip # Not migrated to NNBD
+LibTest/core/RuneIterator/*: Skip # Not migrated to NNBD
+LibTest/core/Runes/*: Skip # Not migrated to NNBD
+LibTest/core/Set/*: Skip # Not migrated to NNBD
+LibTest/core/StackOverflowError/*: Skip # Not migrated to NNBD
+LibTest/core/StackTrace/*: Skip # Not migrated to NNBD
+LibTest/core/StateError/*: Skip # Not migrated to NNBD
+LibTest/core/Stopwatch/*: Skip # Not migrated to NNBD
+LibTest/core/String/*: Skip # Not migrated to NNBD
+LibTest/core/StringBuffer/*: Skip # Not migrated to NNBD
+LibTest/core/Symbol/*: Skip # Not migrated to NNBD
+LibTest/core/TypeError/*: Skip # Not migrated to NNBD
+LibTest/core/UnimplementedError/*: Skip # Not migrated to NNBD
+LibTest/core/UnsupportedError/*: Skip # Not migrated to NNBD
+LibTest/core/Uri/*: Skip # Not migrated to NNBD
+LibTest/core/UriData/*: Skip # Not migrated to NNBD
+LibTest/core/bool/*: Skip # Not migrated to NNBD
+LibTest/core/double/*: Skip # Not migrated to NNBD
+LibTest/core/int/*: Skip # Not migrated to NNBD
+LibTest/html/CanvasRenderingContext2D/*: Skip # Not migrated to NNBD
+LibTest/html/Document/*: Skip # Not migrated to NNBD
+LibTest/html/Element/*: Skip # Not migrated to NNBD
+LibTest/html/Event/*: Skip # Not migrated to NNBD
+LibTest/html/HttpRequest/*: Skip # Not migrated to NNBD
+LibTest/html/HttpRequestUpload/*: Skip # Not migrated to NNBD
+LibTest/html/IFrameElement/*: Skip # Not migrated to NNBD
+LibTest/html/Node/*: Skip # Not migrated to NNBD
+LibTest/html/Window/*: Skip # Not migrated to NNBD
+LibTest/io/BytesBuilder/*: Skip # Not migrated to NNBD
+LibTest/io/CompressionOptions/*: Skip # Not migrated to NNBD
+LibTest/io/ContentType/*: Skip # Not migrated to NNBD
+LibTest/io/Cookie/*: Skip # Not migrated to NNBD
+LibTest/io/Datagram/*: Skip # Not migrated to NNBD
+LibTest/io/Directory/*: Skip # Not migrated to NNBD
+LibTest/io/File/*: Skip # Not migrated to NNBD
+LibTest/io/FileStat/*: Skip # Not migrated to NNBD
+LibTest/io/FileSystemCreateEvent/*: Skip # Not migrated to NNBD
+LibTest/io/FileSystemDeleteEvent/*: Skip # Not migrated to NNBD
+LibTest/io/FileSystemEntity/*: Skip # Not migrated to NNBD
+LibTest/io/FileSystemModifyEvent/*: Skip # Not migrated to NNBD
+LibTest/io/FileSystemMoveEvent/*: Skip # Not migrated to NNBD
+LibTest/io/GZipCodec/*: Skip # Not migrated to NNBD
+LibTest/io/HeaderValue/*: Skip # Not migrated to NNBD
+LibTest/io/HttpClient/*: Skip # Not migrated to NNBD
+LibTest/io/HttpClientBasicCredentials/*: Skip # Not migrated to NNBD
+LibTest/io/HttpClientDigestCredentials/*: Skip # Not migrated to NNBD
+LibTest/io/HttpClientRequest/*: Skip # Not migrated to NNBD
+LibTest/io/HttpClientResponse/*: Skip # Not migrated to NNBD
+LibTest/io/HttpServer/*: Skip # Not migrated to NNBD
+LibTest/io/IOSink/*: Skip # Not migrated to NNBD
+LibTest/io/InternetAddress/*: Skip # Not migrated to NNBD
+LibTest/io/Link/*: Skip # Not migrated to NNBD
+LibTest/io/NetworkInterface/*: Skip # Not migrated to NNBD
+LibTest/io/OSError/*: Skip # Not migrated to NNBD
+LibTest/io/Process/*: Skip # Not migrated to NNBD
+LibTest/io/ProcessInfo/*: Skip # Not migrated to NNBD
+LibTest/io/ProcessResult/*: Skip # Not migrated to NNBD
+LibTest/io/ProcessSignal/*: Skip # Not migrated to NNBD
+LibTest/io/RandomAccessFile/*: Skip # Not migrated to NNBD
+LibTest/io/RawDatagramSocket/*: Skip # Not migrated to NNBD
+LibTest/io/RawSecureServerSocket/*: Skip # Not migrated to NNBD
+LibTest/io/Stdin/*: Skip # Not migrated to NNBD
+LibTest/io/Stdout/*: Skip # Not migrated to NNBD
+LibTest/io/SystemEncoding/*: Skip # Not migrated to NNBD
+LibTest/io/WebSocket/*: Skip # Not migrated to NNBD
+LibTest/io/WebSocketTransformer/*: Skip # Not migrated to NNBD
+LibTest/io/ZLibCodec/*: Skip # Not migrated to NNBD
+LibTest/io/ZLibDecoder/*: Skip # Not migrated to NNBD
+LibTest/io/ZLibEncoder/*: Skip # Not migrated to NNBD
+LibTest/io/certificates/*: Skip # Not migrated to NNBD
+LibTest/io/exit/*: Skip # Not migrated to NNBD
+LibTest/io/exitCode/*: Skip # Not migrated to NNBD
+LibTest/io/gzip/*: Skip # Not migrated to NNBD
+LibTest/io/pid/*: Skip # Not migrated to NNBD
+LibTest/io/sleep/*: Skip # Not migrated to NNBD
+LibTest/io/stderr/*: Skip # Not migrated to NNBD
+LibTest/io/systemEncodingConstant/*: Skip # Not migrated to NNBD
+LibTest/io/zlib/*: Skip # Not migrated to NNBD
+LibTest/isolate/Capability/*: Skip # Not migrated to NNBD
+LibTest/isolate/Isolate/*: Skip # Not migrated to NNBD
+LibTest/isolate/RawReceivePort/*: Skip # Not migrated to NNBD
+LibTest/isolate/ReceivePort/*: Skip # Not migrated to NNBD
+LibTest/isolate/SendPort/*: Skip # Not migrated to NNBD
+LibTest/math/*: Skip # Not migrated to NNBD
+LibTest/math/MutableRectangle/*: Skip # Not migrated to NNBD
+LibTest/math/Point/*: Skip # Not migrated to NNBD
+LibTest/math/Random/*: Skip # Not migrated to NNBD
+LibTest/math/Rectangle/*: Skip # Not migrated to NNBD
+LibTest/mirrors/*: Skip # Not migrated to NNBD
+LibTest/typed_data/*: Skip # Not migrated to NNBD
+LibTest/typed_data/ByteBuffer/*: Skip # Not migrated to NNBD
+LibTest/typed_data/ByteData/*: Skip # Not migrated to NNBD
+LibTest/typed_data/Float32List/*: Skip # Not migrated to NNBD
+LibTest/typed_data/Float32x4/*: Skip # Not migrated to NNBD
+LibTest/typed_data/Float32x4List/*: Skip # Not migrated to NNBD
+LibTest/typed_data/Float64List/*: Skip # Not migrated to NNBD
+LibTest/typed_data/Float64x2/*: Skip # Not migrated to NNBD
+LibTest/typed_data/Float64x2List/*: Skip # Not migrated to NNBD
+LibTest/typed_data/Int16List/*: Skip # Not migrated to NNBD
+LibTest/typed_data/Int32List/*: Skip # Not migrated to NNBD
+LibTest/typed_data/Int32x4/*: Skip # Not migrated to NNBD
+LibTest/typed_data/Int32x4List/*: Skip # Not migrated to NNBD
+LibTest/typed_data/Int64List/*: Skip # Not migrated to NNBD
+LibTest/typed_data/Int8List/*: Skip # Not migrated to NNBD
+LibTest/typed_data/Uint16List/*: Skip # Not migrated to NNBD
+LibTest/typed_data/Uint32List/*: Skip # Not migrated to NNBD
+LibTest/typed_data/Uint64List/*: Skip # Not migrated to NNBD
+LibTest/typed_data/Uint8ClampedList/*: Skip # Not migrated to NNBD
+LibTest/typed_data/Uint8List/*: Skip # Not migrated to NNBD
+
+[ $compiler != fasta ]
+Language/Classes/Abstract_Instance_Members/inherited_t13: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Abstract_Instance_Members/inherited_t14: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Abstract_Instance_Members/inherited_t15: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Abstract_Instance_Members/invocation_t05: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Abstract_Instance_Members/invocation_t06: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Abstract_Instance_Members/override_default_value_t10: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Abstract_Instance_Members/override_less_positional_parameters_t03: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Abstract_Instance_Members/override_more_required_parameters_t05: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Abstract_Instance_Members/override_no_named_parameters_t07: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Abstract_Instance_Members/override_not_a_subtype_t05: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Abstract_Instance_Members/same_name_static_method_in_superclass_t07: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Constructors/Constant_Constructors/name_t01: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Constructors/Constant_Constructors/not_a_constant_in_superclass_t03: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Constructors/Constant_Constructors/superinitializer_t05: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Constructors/Constant_Constructors/superinitializer_t06: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Constructors/Factories/name_t06: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Constructors/Factories/name_t07: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Constructors/Factories/redirecting_constructor_call_t03: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Constructors/Factories/redirecting_constructor_t04: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Constructors/Factories/redirecting_to_itself_t05: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Constructors/Factories/redirecting_to_itself_t06: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Constructors/Factories/redirecting_to_itself_t07: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Constructors/Factories/return_type_t08: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Constructors/Factories/return_wrong_type_t08: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Constructors/Factories/return_wrong_type_t09: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Constructors/Factories/return_wrong_type_t10: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Constructors/Generative_Constructors/execution_of_a_superinitializer_t02: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Constructors/Generative_Constructors/formal_parameter_t09: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Constructors/Generative_Constructors/formal_parameter_t10: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Constructors/Generative_Constructors/formal_parameter_t11: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Constructors/Generative_Constructors/implicit_superinitializer_t03: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Constructors/Generative_Constructors/implicit_superinitializer_t04: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Constructors/Generative_Constructors/initializers_t17: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Constructors/Generative_Constructors/name_t01: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Constructors/Generative_Constructors/superinitializer_t04: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Constructors/implicit_constructor_t04: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Constructors/implicit_constructor_t05: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Constructors/name_t08: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Constructors/wrong_name_t02: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Constructors/wrong_name_t03: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Getters/instance_getter_t13: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Getters/instance_getter_t14: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Getters/override_t05: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Getters/same_name_method_t13: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Getters/same_name_method_t14: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Getters/type_object_t03: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Instance_Methods/override_different_default_values_t03: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Instance_Methods/override_fewer_parameters_t03: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Instance_Methods/override_more_parameters_t03: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Instance_Methods/override_named_parameters_t07: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Instance_Methods/override_named_parameters_t08: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Instance_Methods/override_named_parameters_t09: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Instance_Methods/override_named_parameters_t10: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Instance_Methods/override_named_parameters_t11: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Instance_Methods/override_subtype_t07: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Instance_Methods/override_subtype_t08: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Instance_Methods/override_subtype_t09: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Instance_Methods/override_subtype_t10: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Instance_Methods/override_subtype_t11: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Instance_Methods/override_subtype_t12: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Instance_Methods/same_name_getter_t03: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Instance_Methods/same_name_setter_t03: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t10: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t11: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Instance_Variables/definition_t05: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Instance_Variables/type_aliases_t01: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Instance_Variables/type_aliases_t02: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Instance_Variables/type_aliases_t03: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Setters/syntax_t06: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Static_Methods/declaration_t04: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Static_Variables/inheritance_t02: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Static_Variables/type_alias_t01: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Superclasses/Inheritance_and_Overriding/abstract_method_t02: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Superclasses/Inheritance_and_Overriding/inheritance_t08: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Superclasses/Inheritance_and_Overriding/inheritance_t09: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Superclasses/Inheritance_and_Overriding/inheritance_t10: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Superclasses/Inheritance_and_Overriding/overriding_t06: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Superclasses/Inheritance_and_Overriding/overriding_t07: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Superclasses/Inheritance_and_Overriding/overriding_t08: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Superclasses/extends_clause_t02: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Superclasses/superclass_of_itself_t03: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Superclasses/superclass_of_itself_t04: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Superclasses/transition_t02: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Superinterfaces/dynamic_type_t03: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Superinterfaces/implicit_interface_t03: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Superinterfaces/itself_t02: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Superinterfaces/more_than_once_t02: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Superinterfaces/no_member_t06: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Superinterfaces/no_member_t07: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Superinterfaces/superclass_as_superinterface_t02: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Superinterfaces/superclass_as_superinterface_t03: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Superinterfaces/superclass_as_superinterface_t04: Skip # github.com/dart-lang/language/issues/115
+Language/Classes/Superinterfaces/syntax_t03: Skip # github.com/dart-lang/language/issues/115
+Language/Enums/restrictions_t09: Skip # github.com/dart-lang/language/issues/115
+Language/Enums/restrictions_t10: Skip # github.com/dart-lang/language/issues/115
+Language/Enums/restrictions_t11: Skip # github.com/dart-lang/language/issues/115
+Language/Enums/restrictions_t12: Skip # github.com/dart-lang/language/issues/115
+Language/Enums/syntax_t10: Skip # github.com/dart-lang/language/issues/115
+Language/Expressions/Instance_Creation/New/type_t08: Skip # github.com/dart-lang/language/issues/115
+Language/Expressions/Instance_Creation/New/type_t09: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/Superbounded_types/typedef3_A01_t01: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/Superbounded_types/typedef3_A01_t02: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/Superbounded_types/typedef3_A01_t03: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/Superbounded_types/typedef3_A01_t04: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/Superbounded_types/typedef3_A01_t05: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/Superbounded_types/typedef3_A01_t06: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/parameter_A01_t03: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/parameter_A01_t04: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/parameter_A02_t03: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/parameter_A03_t03: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/parameter_A04_t03: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/parameter_A09_t03: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/syntax_t20: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/syntax_t21: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/syntax_t22: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/syntax_t23: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/syntax_t24: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/syntax_t25: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/syntax_t27: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/syntax_t28: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/syntax_t29: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/syntax_t30: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/typedef_A01_t01: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/typedef_A01_t02: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/typedef_A01_t03: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/typedef_A01_t04: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/typedef_A01_t05: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/typedef_A01_t06: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/typedef_A01_t07: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/typedef_A01_t08: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/typedef_A01_t10: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/typedef_A04_t01: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/typedef_A04_t02: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/typedef_A06_t01: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/typedef_A06_t02: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/typedef_A06_t03: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/typedef_A06_t04: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/typedef_A06_t05: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/typedef_A06_t06: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/typedef_A06_t07: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/typedef_A06_t08: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/typedef_A06_t09: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/typedef_A06_t10: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/typedef_A06_t11: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/typedef_A06_t12: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/typedef_A06_t13: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/typedef_A06_t14: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/typedef_A07_t01: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/typedef_A08_t01: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/typedef_A09_t05: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/typedef_A09_t06: Skip # github.com/dart-lang/language/issues/115
+Language/Generics/typedef_A10_t01: Skip # github.com/dart-lang/language/issues/115
+Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/inheritance_t09: Skip # github.com/dart-lang/language/issues/115
+Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/inheritance_t10: Skip # github.com/dart-lang/language/issues/115
+Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/inheritance_t11: Skip # github.com/dart-lang/language/issues/115
+Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/inheritance_t12: Skip # github.com/dart-lang/language/issues/115
+Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/inheritance_t13: Skip # github.com/dart-lang/language/issues/115
+Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/inheritance_t14: Skip # github.com/dart-lang/language/issues/115
+Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/not_overriden_members_t03: Skip # github.com/dart-lang/language/issues/115
+Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/not_overriden_members_t04: Skip # github.com/dart-lang/language/issues/115
+Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_getters_t03: Skip # github.com/dart-lang/language/issues/115
+Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_getters_t04: Skip # github.com/dart-lang/language/issues/115
+Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_getters_type_t10: Skip # github.com/dart-lang/language/issues/115
+Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_getters_type_t11: Skip # github.com/dart-lang/language/issues/115
+Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_getters_type_t12: Skip # github.com/dart-lang/language/issues/115
+Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_members_t03: Skip # github.com/dart-lang/language/issues/115
+Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_method_and_getter_t03: Skip # github.com/dart-lang/language/issues/115
+Language/Interfaces/Superinterfaces/definition_t06: Skip # github.com/dart-lang/language/issues/115
+Language/Interfaces/Superinterfaces/superinterface_of_itself_t04: Skip # github.com/dart-lang/language/issues/115
+Language/Mixins/Mixin_Application/abstract_t09: Skip # github.com/dart-lang/language/issues/115
+Language/Mixins/Mixin_Application/abstract_t10: Skip # github.com/dart-lang/language/issues/115
+Language/Mixins/Mixin_Application/abstract_t11: Skip # github.com/dart-lang/language/issues/115
+Language/Mixins/Mixin_Application/abstract_t12: Skip # github.com/dart-lang/language/issues/115
+Language/Mixins/Mixin_Application/abstract_t13: Skip # github.com/dart-lang/language/issues/115
+Language/Mixins/Mixin_Application/deferred_t03: Skip # github.com/dart-lang/language/issues/115
+Language/Mixins/Mixin_Application/implicit_constructor_t03: Skip # github.com/dart-lang/language/issues/115
+Language/Mixins/Mixin_Application/implicit_constructor_t04: Skip # github.com/dart-lang/language/issues/115
+Language/Mixins/Mixin_Application/initializers_t04: Skip # github.com/dart-lang/language/issues/115
+Language/Mixins/Mixin_Application/initializers_t05: Skip # github.com/dart-lang/language/issues/115
+Language/Mixins/Mixin_Application/initializers_t06: Skip # github.com/dart-lang/language/issues/115
+Language/Mixins/Mixin_Application/interfaces_t06: Skip # github.com/dart-lang/language/issues/115
+Language/Mixins/Mixin_Application/interfaces_t07: Skip # github.com/dart-lang/language/issues/115
+Language/Mixins/Mixin_Application/superclass_t03: Skip # github.com/dart-lang/language/issues/115
+Language/Mixins/Mixin_Application/superclass_t04: Skip # github.com/dart-lang/language/issues/115
+Language/Mixins/Mixin_Application/superinterfaces_t10: Skip # github.com/dart-lang/language/issues/115
+Language/Mixins/Mixin_Application/superinterfaces_t11: Skip # github.com/dart-lang/language/issues/115
+Language/Mixins/Mixin_Application/superinterfaces_t12: Skip # github.com/dart-lang/language/issues/115
+Language/Mixins/Mixin_Application/superinterfaces_t13: Skip # github.com/dart-lang/language/issues/115
+Language/Mixins/Mixin_Application/superinterfaces_t14: Skip # github.com/dart-lang/language/issues/115
+Language/Mixins/Mixin_Application/syntax_t26: Skip # github.com/dart-lang/language/issues/115
+Language/Mixins/Mixin_Application/warning_t04: Skip # github.com/dart-lang/language/issues/115
+Language/Mixins/Mixin_Application/wrong_mixin_type_t09: Skip # github.com/dart-lang/language/issues/115
+Language/Mixins/Mixin_Composition/order_t02: Skip # github.com/dart-lang/language/issues/115
+Language/Mixins/declaring_constructor_t11: Skip # github.com/dart-lang/language/issues/115
+Language/Types/Type_Aliases/built-in_types_t01: Skip # github.com/dart-lang/language/issues/115
+Language/Types/Type_Aliases/built-in_types_t02: Skip # github.com/dart-lang/language/issues/115
+Language/Types/Type_Aliases/built-in_types_t03: Skip # github.com/dart-lang/language/issues/115
+Language/Types/Type_Aliases/built-in_types_t04: Skip # github.com/dart-lang/language/issues/115
+Language/Types/Type_Aliases/built-in_types_t05: Skip # github.com/dart-lang/language/issues/115
+Language/Types/Type_Aliases/built-in_types_t06: Skip # github.com/dart-lang/language/issues/115
+Language/Types/Type_Aliases/built-in_types_t07: Skip # github.com/dart-lang/language/issues/115
+Language/Types/Type_Aliases/built-in_types_t08: Skip # github.com/dart-lang/language/issues/115
+Language/Types/Type_Aliases/built-in_types_t09: Skip # github.com/dart-lang/language/issues/115
+Language/Types/Type_Aliases/built-in_types_t10: Skip # github.com/dart-lang/language/issues/115
+Language/Types/Type_Aliases/built-in_types_t11: Skip # github.com/dart-lang/language/issues/115
+Language/Types/Type_Aliases/built-in_types_t12: Skip # github.com/dart-lang/language/issues/115
+Language/Types/Type_Aliases/scope_t01: Skip # github.com/dart-lang/language/issues/115
+Language/Types/Type_Aliases/scope_t02: Skip # github.com/dart-lang/language/issues/115
+Language/Types/Type_Aliases/scope_t03: Skip # github.com/dart-lang/language/issues/115
+Language/Types/Type_Aliases/scope_t04: Skip # github.com/dart-lang/language/issues/115
+Language/Types/Type_Aliases/self_reference_t19: Skip # github.com/dart-lang/language/issues/115
+Language/Types/Type_Aliases/self_reference_t20: Skip # github.com/dart-lang/language/issues/115
+Language/Types/Type_Aliases/self_reference_t21: Skip # github.com/dart-lang/language/issues/115
+Language/Types/Type_Aliases/self_reference_t22: Skip # github.com/dart-lang/language/issues/115
+Language/Types/Type_Aliases/self_reference_t23: Skip # github.com/dart-lang/language/issues/115
+Language/Types/Type_Aliases/self_reference_t24: Skip # github.com/dart-lang/language/issues/115
+Language/Types/Type_Aliases/self_reference_t25: Skip # github.com/dart-lang/language/issues/115
+Language/Types/Type_Aliases/syntax_t01: Skip # github.com/dart-lang/language/issues/115
+Language/Types/Type_Aliases/syntax_t02: Skip # github.com/dart-lang/language/issues/115
+Language/Types/Type_Aliases/syntax_t03: Skip # github.com/dart-lang/language/issues/115
+Language/Types/Type_Aliases/syntax_t04: Skip # github.com/dart-lang/language/issues/115
+Language/Types/Type_Aliases/syntax_t05: Skip # github.com/dart-lang/language/issues/115
+Language/Types/Type_Aliases/syntax_t06: Skip # github.com/dart-lang/language/issues/115
+Language/Types/Type_Aliases/syntax_t20: Skip # github.com/dart-lang/language/issues/115
+Language/Types/Type_Aliases/syntax_t21: Skip # github.com/dart-lang/language/issues/115
+LanguageFeatures/Instantiate-to-bound/nonfunction_typedef/dynamic/*: Skip # github.com/dart-lang/language/issues/115
+LanguageFeatures/Instantiate-to-bound/nonfunction_typedef/static/*: Skip # github.com/dart-lang/language/issues/115
+LanguageFeatures/Simple-bounds/dynamic/typedef1_FutureOr_l1_t01: Skip # github.com/dart-lang/language/issues/115
+LanguageFeatures/Simple-bounds/dynamic/typedef1_FutureOr_l1_t02: Skip # github.com/dart-lang/language/issues/115
+LanguageFeatures/Simple-bounds/dynamic/typedef1_l1_t01: Skip # github.com/dart-lang/language/issues/115
+LanguageFeatures/Simple-bounds/dynamic/typedef1_l1_t02: Skip # github.com/dart-lang/language/issues/115
+LanguageFeatures/Simple-bounds/dynamic/typedef1_l1_t03: Skip # github.com/dart-lang/language/issues/115
+LanguageFeatures/Simple-bounds/dynamic/typedef1_l1_t04: Skip # github.com/dart-lang/language/issues/115
+LanguageFeatures/Simple-bounds/dynamic/typedef1_l2_t01: Skip # github.com/dart-lang/language/issues/115
+LanguageFeatures/Simple-bounds/dynamic/typedef1_l2_t02: Skip # github.com/dart-lang/language/issues/115
+LanguageFeatures/Simple-bounds/dynamic/typedef1_typedef_l1_t01: Skip # github.com/dart-lang/language/issues/115
+LanguageFeatures/Simple-bounds/dynamic/typedef1_typedef_l1_t02: Skip # github.com/dart-lang/language/issues/115
+LanguageFeatures/Simple-bounds/dynamic/typedef1_typedef_l1_t03: Skip # github.com/dart-lang/language/issues/115
+LanguageFeatures/Simple-bounds/dynamic/typedef1_typedef_l1_t04: Skip # github.com/dart-lang/language/issues/115
+LanguageFeatures/Simple-bounds/dynamic/typedef1_typedef_l1_t05: Skip # github.com/dart-lang/language/issues/115
+LanguageFeatures/Simple-bounds/dynamic/typedef1_typedef_l1_t07: Skip # github.com/dart-lang/language/issues/115
+LanguageFeatures/Simple-bounds/dynamic/typedef1_typedef_l1_t08: Skip # github.com/dart-lang/language/issues/115
+LanguageFeatures/Simple-bounds/static/typedef1_FutureOr_l1_t01: Skip # github.com/dart-lang/language/issues/115
+LanguageFeatures/Simple-bounds/static/typedef1_FutureOr_l1_t02: Skip # github.com/dart-lang/language/issues/115
+LanguageFeatures/Simple-bounds/static/typedef1_l1_t01: Skip # github.com/dart-lang/language/issues/115
+LanguageFeatures/Simple-bounds/static/typedef1_l1_t02: Skip # github.com/dart-lang/language/issues/115
+LanguageFeatures/Simple-bounds/static/typedef1_l1_t03: Skip # github.com/dart-lang/language/issues/115
+LanguageFeatures/Simple-bounds/static/typedef1_l1_t04: Skip # github.com/dart-lang/language/issues/115
+LanguageFeatures/Simple-bounds/static/typedef1_l2_t01: Skip # github.com/dart-lang/language/issues/115
+LanguageFeatures/Simple-bounds/static/typedef1_l2_t02: Skip # github.com/dart-lang/language/issues/115
+LanguageFeatures/Simple-bounds/static/typedef1_typedef_l1_t01: Skip # github.com/dart-lang/language/issues/115
+LanguageFeatures/Simple-bounds/static/typedef1_typedef_l1_t02: Skip # github.com/dart-lang/language/issues/115
+LanguageFeatures/Simple-bounds/static/typedef1_typedef_l1_t03: Skip # github.com/dart-lang/language/issues/115
+LanguageFeatures/Simple-bounds/static/typedef1_typedef_l1_t04: Skip # github.com/dart-lang/language/issues/115
+LanguageFeatures/Simple-bounds/static/typedef1_typedef_l1_t05: Skip # github.com/dart-lang/language/issues/115
+LanguageFeatures/Simple-bounds/static/typedef1_typedef_l1_t06: Skip # github.com/dart-lang/language/issues/115
+LanguageFeatures/Simple-bounds/static/typedef1_typedef_l1_t07: Skip # github.com/dart-lang/language/issues/115
+LanguageFeatures/Simple-bounds/static/typedef1_typedef_l1_t08: Skip # github.com/dart-lang/language/issues/115
+LanguageFeatures/regression/32903_t02: Skip # github.com/dart-lang/language/issues/115
+LanguageFeatures/regression/34560_t02: Skip # github.com/dart-lang/language/issues/115
+
+[ $runtime != none ]
+LibTest/async/Completer/completeError_A02_t01: Skip # See breaking change #40674
+LibTest/async/Future/Future.error_A01_t01: Skip # See breaking change #40674
+LibTest/async/StreamController/addError_A02_t01: Skip # See breaking change #40674
+LibTest/collection/HashSet/HashSet.from_A02_t01: Skip # See breaking change #40674
+LibTest/collection/ListQueue/ListQueue.from_A03_t01: Skip # See breaking change #40674
+LibTest/core/RuneIterator/RuneIterator.at_A01_t01: Skip # See breaking change #40674
+LibTest/core/RuneIterator/RuneIterator.at_A02_t01: Skip # See breaking change #40674
+LibTest/core/RuneIterator/RuneIterator.at_A03_t01: Skip # See breaking change #40674
+LibTest/core/RuneIterator/RuneIterator_A01_t01: Skip # See breaking change #40674
+LibTest/core/RuneIterator/currentAsString_A03_t01: Skip # See breaking change #40674
+LibTest/core/RuneIterator/movePrevious_A02_t02: Skip # See breaking change #40674
+LibTest/core/RuneIterator/rawIndex_A02_t01: Skip # See breaking change #40674
+LibTest/core/RuneIterator/reset_A01_t01: Skip # See breaking change #40674
+LibTest/core/RuneIterator/reset_A01_t02: Skip # See breaking change #40674
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
new file mode 100644
index 0000000..dddded9
--- /dev/null
+++ b/tests/co19/co19-dart2js.status
@@ -0,0 +1,34 @@
+# Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+[ $compiler == dart2js ]
+Language/Expressions/Null/instance_of_class_null_t01: Skip # dart:mirrors not supported https://github.com/dart-lang/co19/issues/522.
+Language/Expressions/Spawning_an_Isolate/new_isolate_t01: SkipByDesign
+Language/Metadata/before*: Skip # dart:mirrors not supported https://github.com/dart-lang/co19/issues/523.
+LibTest/io/*: SkipByDesign # dart:io not supported.
+LibTest/isolate/*: SkipByDesign # dart:isolate not supported.
+
+[ $compiler == dart2js && $runtime == d8 ]
+LibTest/html/*: SkipByDesign # d8 is not a browser
+
+[ $compiler == dart2js && $runtime == d8 && $host_checked ]
+LibTest/collection/ListBase/ListBase_class_A01_t04: Slow, Pass
+LibTest/collection/ListBase/ListBase_class_A01_t05: Slow, Pass
+LibTest/collection/ListBase/ListBase_class_A01_t06: Slow, Pass
+LibTest/collection/ListMixin/ListMixin_class_A01_t04: Slow, Pass
+LibTest/collection/ListMixin/ListMixin_class_A01_t05: Slow, Pass
+LibTest/collection/ListMixin/ListMixin_class_A01_t06: Slow, Pass
+LibTest/core/List/List_class_A01_t05: Slow, Pass
+LibTest/core/List/List_class_A01_t06: Slow, Pass
+
+[ $compiler == dart2js && $runtime == ie11 ]
+LibTest/collection/ListBase/ListBase_class_A01_t04: SkipSlow # slow babeljs transformation
+LibTest/collection/ListBase/ListBase_class_A01_t05: SkipSlow # slow babeljs transformation
+LibTest/collection/ListBase/ListBase_class_A01_t06: SkipSlow # slow babeljs transformation
+LibTest/collection/ListMixin/ListMixin_class_A01_t04: SkipSlow # slow babeljs transformation
+LibTest/collection/ListMixin/ListMixin_class_A01_t05: SkipSlow # slow babeljs transformation
+LibTest/collection/ListMixin/ListMixin_class_A01_t06: SkipSlow # slow babeljs transformation
+LibTest/core/List/List_class_A01_t04: SkipSlow # slow babeljs transformation
+LibTest/core/List/List_class_A01_t05: SkipSlow # slow babeljs transformation
+LibTest/core/List/List_class_A01_t06: SkipSlow # slow babeljs transformation
diff --git a/tests/co19/co19-dartdevc.status b/tests/co19/co19-dartdevc.status
new file mode 100644
index 0000000..087f30b
--- /dev/null
+++ b/tests/co19/co19-dartdevc.status
@@ -0,0 +1,83 @@
+# Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+[ $compiler == dartdevc || $compiler == dartdevk ]
+Language/Classes/Constructors/Generative_Constructors/formal_parameter_t07: Skip # Times out
+Language/Classes/Constructors/Generative_Constructors/fresh_instance_t01: Skip # Times out
+Language/Classes/Constructors/Generative_Constructors/implicit_superinitializer_t01: Skip # Times out
+Language/Classes/Constructors/Generative_Constructors/implicit_superinitializer_t02: Skip # Times out
+Language/Classes/Constructors/Generative_Constructors/initializers_t01: Skip # Times out
+Language/Classes/Constructors/Generative_Constructors/initializers_t15: Skip # Times out
+Language/Classes/Constructors/Generative_Constructors/initializing_formals_execution_t01: Skip # Times out
+Language/Classes/Constructors/Generative_Constructors/initializing_this_t01: Skip # Times out
+Language/Classes/Constructors/Generative_Constructors/redirection_t01: Skip # Times out
+Language/Classes/Constructors/Generative_Constructors/syntax_t01: Skip # Times out
+Language/Classes/Constructors/implicit_constructor_t01: Skip # Times out
+Language/Classes/Constructors/implicit_constructor_t02: Skip # Times out
+Language/Classes/Constructors/name_t01: Skip # Times out
+Language/Classes/Constructors/name_t02: Skip # Times out
+Language/Classes/Constructors/name_t03: Skip # Times out
+Language/Classes/Getters/instance_getter_t01: Skip # Times out
+Language/Classes/Getters/instance_getter_t02: Skip # Times out
+Language/Classes/Getters/instance_getter_t03: Skip # Times out
+Language/Classes/Getters/instance_getter_t04: Skip # Times out
+Language/Classes/Getters/instance_getter_t05: Skip # Times out
+Language/Classes/Getters/instance_getter_t06: Skip # Times out
+Language/Classes/Getters/override_t04: Skip # Times out
+Language/Classes/Getters/return_type_t01: Skip # Times out
+Language/Classes/Getters/static_t01/none: Skip # Times out
+Language/Classes/Getters/static_t02: Skip # Times out
+Language/Classes/Getters/syntax_t01: Skip # Times out
+Language/Classes/Getters/void_return_type_t01: Skip # Times out
+Language/Classes/Instance_Methods/Operators/allowed_names_t01: Skip # Times out
+Language/Classes/Instance_Methods/Operators/arity_0_or_1_t01: Skip # Times out
+Language/Classes/Instance_Methods/Operators/arity_0_t01: Skip # Times out
+Language/Classes/Instance_Methods/Operators/syntax_t01: Skip # Times out
+Language/Classes/Instance_Methods/Operators/syntax_t03: Skip # Times out
+Language/Classes/Instance_Methods/override_named_parameters_t03: Skip # Times out
+Language/Classes/Instance_Methods/override_named_parameters_t04: Skip # Times out
+Language/Classes/Instance_Methods/override_named_parameters_t06: Skip # Times out
+Language/Classes/Instance_Methods/override_subtype_t05: Skip # Times out
+Language/Classes/Instance_Methods/override_subtype_t06: Skip # Times out
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t01: Skip # Times out
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t02: Skip # Times out
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t04: Skip # Times out
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t05: Skip # Times out
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t06: Skip # Times out
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t07: Skip # Times out
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t08: Skip # Times out
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t09: Skip # Times out
+Language/Classes/Instance_Variables/definition_t01: Skip # Times out
+Language/Classes/Instance_Variables/definition_t02: Skip # Times out
+Language/Classes/Instance_Variables/definition_t04: Skip # Times out
+Language/Classes/Setters/instance_setter_t01: Skip # Times out
+Language/Expressions/Function_Invocation/async_generator_invokation_t08: Skip # Times out
+Language/Expressions/Function_Invocation/async_generator_invokation_t10: Skip # Times out
+Language/Expressions/Null/instance_of_class_null_t01: Skip # dart:mirrors not supported https://github.com/dart-lang/co19/issues/522.
+Language/Expressions/Spawning_an_Isolate/new_isolate_t01: SkipByDesign # dart:isolate not supported.
+Language/Metadata/before*: Skip # dart:mirrors not supported https://github.com/dart-lang/co19/issues/523.
+Language/Types/Interface_Types/subtype_t27: Skip # Times out
+Language/Types/Interface_Types/subtype_t28: Skip # Times out
+LibTest/html/CanvasRenderingContext2D/addEventListener_A01_t03: Skip # Times out
+LibTest/html/Element/blur_A01_t01: Skip # Times out
+LibTest/html/Element/focus_A01_t01: Skip # Times out
+LibTest/html/Element/loadEvent_A01_t01: Skip # Times out
+LibTest/html/Element/mouseWheelEvent_A01_t01: Skip # Times out
+LibTest/html/Element/onLoad_A01_t01: Skip # Times out
+LibTest/html/Element/onMouseWheel_A01_t01: Skip # Times out
+LibTest/html/Element/onTransitionEnd_A01_t01: Skip # Times out
+LibTest/html/Element/transitionEndEvent_A01_t01: Skip # Times out
+LibTest/html/HttpRequest/onError_A01_t02: Skip # Times out
+LibTest/html/HttpRequest/responseText_A01_t02: Skip # Times out
+LibTest/html/HttpRequestUpload/onError_A01_t02: Skip # Times out
+LibTest/html/HttpRequestUpload/onLoadEnd_A01_t01: Skip # Times out
+LibTest/html/HttpRequestUpload/onLoadStart_A01_t01: Skip # Times out
+LibTest/html/HttpRequestUpload/onLoad_A01_t01: Skip # Times out
+LibTest/html/IFrameElement/blur_A01_t01: Skip # Times out
+LibTest/html/IFrameElement/enteredView_A01_t01: Skip # Times out
+LibTest/html/IFrameElement/focus_A01_t01: Skip # Times out
+LibTest/html/IFrameElement/onMouseWheel_A01_t01: Skip # Times out
+LibTest/html/IFrameElement/onTransitionEnd_A01_t01: Skip # Times out
+LibTest/io/*: SkipByDesign # dart:io not supported.
+LibTest/isolate/*: SkipByDesign # dart:isolate not supported.
diff --git a/tests/co19/co19-kernel.status b/tests/co19/co19-kernel.status
new file mode 100644
index 0000000..8aa80ab
--- /dev/null
+++ b/tests/co19/co19-kernel.status
@@ -0,0 +1,205 @@
+# Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+[ $builder_tag == bytecode_interpreter ]
+LibTest/collection/ListBase/ListBase_class_A01_t04: Slow, Pass
+LibTest/collection/ListBase/ListBase_class_A01_t05: Slow, Pass
+LibTest/collection/ListBase/ListBase_class_A01_t06: Slow, Pass
+
+[ $compiler == dartkb ]
+LibTest/isolate/Isolate/kill_A01_t01: Skip # Issue 37699
+LibTest/isolate/Isolate/pause_A01_t01: Skip # Issue 37699
+LibTest/isolate/Isolate/pause_A01_t02: Skip # Issue 37699
+
+[ $compiler == fasta ]
+Language/Statements/For/syntax_t13: Crash # Assertion error: kernel_shadow_ast.dart: 'receiver == null': is not true.
+Language/Statements/For/syntax_t20: Crash # Assertion error: kernel_shadow_ast.dart: 'receiver == null': is not true.
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t06/none: Crash
+
+[ $runtime == vm ]
+LibTest/collection/ListBase/ListBase_class_A01_t02: Slow, Pass # Does many calls
+LibTest/collection/ListMixin/ListMixin_class_A01_t02: Slow, Pass # Does many calls
+LibTest/core/List/List_class_A01_t02: Slow, Pass # Does many calls
+LibTest/io/RawDatagramSocket/*: Skip # RawDatagramSocket are flacky. Skip them all until rewritten
+
+[ $fasta ]
+Language/Classes/Instance_Methods/Operators/allowed_names_t01: Skip # triple-shift flag
+Language/Classes/Instance_Methods/Operators/allowed_names_t23: Skip # triple-shift flag
+Language/Classes/Instance_Methods/Operators/arity_1_t19: Skip # triple-shift flag
+Language/Enums/restrictions_t10: Crash
+Language/Expressions/Assignment/Compound_Assignment/expression_assignment_t12: Skip # triple-shift flag
+Language/Expressions/Assignment/Compound_Assignment/indexed_expression_assignment_t12: Skip # triple-shift flag
+Language/Expressions/Assignment/Compound_Assignment/null_aware_compound_assignment_static_t12: Skip # triple-shift flag
+Language/Expressions/Assignment/Compound_Assignment/null_aware_compound_assignment_t12: Skip # triple-shift flag
+Language/Expressions/Assignment/Compound_Assignment/setter_assignment_t12: Skip # triple-shift flag
+Language/Expressions/Assignment/Compound_Assignment/variable_assignment_t12: Skip # triple-shift flag
+Language/Expressions/Bitwise_Expressions/syntax_t01: Skip # triple-shift flag
+Language/Expressions/Constants/bitwise_operators_t01: Skip # triple-shift flag
+Language/Expressions/Constants/bitwise_operators_t07: Skip # triple-shift flag
+Language/Expressions/Constants/bitwise_operators_t08: Skip # triple-shift flag
+Language/Expressions/Equality/syntax_t01: Skip # triple-shift flag
+Language/Expressions/Lists/syntax_t01: Skip # triple-shift flag
+Language/Expressions/Maps/syntax_t01: Skip # triple-shift flag
+Language/Expressions/Relational_Expressions/syntax_t01: Skip # triple-shift experiment flag
+Language/Expressions/Shift/allowed_characters_t02: Skip # triple-shift flag
+Language/Expressions/Shift/equivalent_super_t02: Skip # triple-shift flag
+Language/Expressions/Shift/equivalent_t02: Skip # triple-shift flag
+Language/Expressions/Shift/integer_t03: Skip # triple-shift flag
+Language/Expressions/Shift/integer_t04/01: Crash
+Language/Expressions/Shift/integer_t04/02: Crash
+Language/Expressions/Shift/integer_t04/03: Crash
+Language/Expressions/Shift/integer_t04/04: Crash
+Language/Expressions/Shift/integer_t04/05: Crash
+Language/Expressions/Shift/integer_t04/06: Crash
+Language/Expressions/Shift/integer_t04/07: Crash
+Language/Expressions/Shift/integer_t04/none: Crash
+Language/Expressions/Shift/syntax_t01: Skip # triple-shift experiment flag
+Language/Expressions/Shift/syntax_t15: Skip # triple-shift experiment flag
+Language/Expressions/Shift/syntax_t17: Skip # triple-shift experiment flag
+Language/Expressions/Shift/syntax_t18: Skip # triple-shift experiment flag
+Language/Expressions/Shift/syntax_t19: Skip # triple-shift experiment flag
+Language/Expressions/Shift/syntax_t21: Skip # triple-shift experiment flag
+Language/Expressions/Shift/syntax_t22: Skip # triple-shift experiment flag
+Language/Expressions/Shift/syntax_t23: Skip # triple-shift experiment flag
+Language/Expressions/Shift/syntax_t24: Skip # triple-shift experiment flag
+Language/Expressions/Shift/syntax_t25: Skip # triple-shift experiment flag
+Language/Expressions/Shift/syntax_t26: Skip # triple-shift experiment flag
+Language/Expressions/Shift/syntax_t27: Skip # triple-shift experiment flag
+Language/Expressions/Strings/String_Interpolation/syntax_t01: Skip # triple-shift experiment flag
+Language/Expressions/Symbols/syntax_t02: Skip # triple-shift experiment flag
+Language/Expressions/parentheses_t01: Skip # triple-shift experiment flag
+Language/Functions/syntax_t03: Skip # triple-shift experiment flag
+Language/Mixins/Mixin_Application/abstract_t09: Crash
+Language/Mixins/Mixin_Application/abstract_t10: Crash
+Language/Mixins/Mixin_Application/abstract_t11: Crash
+Language/Mixins/Mixin_Application/abstract_t12: Crash
+Language/Mixins/Mixin_Application/abstract_t13: Crash
+Language/Mixins/Mixin_Application/deferred_t03: Crash
+Language/Mixins/Mixin_Application/implicit_constructor_t03: Crash
+Language/Mixins/Mixin_Application/implicit_constructor_t04: Crash
+Language/Mixins/Mixin_Application/initializers_t04: Crash
+Language/Mixins/Mixin_Application/initializers_t05: Crash
+Language/Mixins/Mixin_Application/initializers_t06: Crash
+Language/Mixins/Mixin_Application/interfaces_t06: Crash
+Language/Mixins/Mixin_Application/interfaces_t07: Crash
+Language/Mixins/Mixin_Application/superclass_t03: Crash
+Language/Mixins/Mixin_Application/superclass_t04: Crash
+Language/Mixins/Mixin_Application/superinterfaces_t10: Crash
+Language/Mixins/Mixin_Application/superinterfaces_t11: Crash
+Language/Mixins/Mixin_Application/superinterfaces_t13: Crash
+Language/Mixins/Mixin_Application/superinterfaces_t14: Crash
+Language/Mixins/Mixin_Application/syntax_t26: Crash
+Language/Mixins/Mixin_Application/warning_t04: Crash
+Language/Mixins/Mixin_Application/wrong_mixin_type_t09: Crash
+Language/Mixins/Mixin_Composition/order_t02: Crash
+Language/Mixins/declaring_constructor_t11: Crash
+Language/Reference/Operator_Precedence/precedence_01_assignment_t14: Skip # triple-shift experimental flag
+Language/Reference/Operator_Precedence/precedence_12_Shift_t04: Skip # triple-shift experimental flag
+Language/Reference/Operator_Precedence/precedence_t05: Skip # triple-shift experimental flag
+Language/Statements/Expression_Statements/syntax_t06: Skip # triple-shift experimental flag
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t01: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t02: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t03/01: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t03/02: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t03/03: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t03/04: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t03/05: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t03/06: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t03/none: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t04: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t04/01: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t04/02: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t04/03: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t04/04: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t04/none: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t05/01: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t05/02: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t05/03: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t05/04: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t05/05: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t05/06: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t05/none: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t06/01: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t06/02: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t06/03: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t06/04: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t06/05: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t06/06: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t07: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t07/01: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t07/02: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t07/03: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t07/04: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t07/05: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t07/06: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t07/none: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t08/01: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t08/02: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t08/03: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t08/04: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t08/05: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t08/none: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t09: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t10/01: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t10/02: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t10/03: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t10/04: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t10/05: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t10/06: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t10/none: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t11: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t12/01: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t12/02: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t12/03: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t12/04: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t12/05: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t12/none: Crash
+LanguageFeatures/Instantiate-to-bound/class/dynamic/class_FutureOr_l1_t01: Crash
+LanguageFeatures/Instantiate-to-bound/class/dynamic/class_FutureOr_l1_t03: Crash
+LanguageFeatures/Instantiate-to-bound/class/static/class_FutureOr_l1_t01: Crash
+LanguageFeatures/Instantiate-to-bound/class/static/class_FutureOr_l1_t01/01: Crash
+LanguageFeatures/Instantiate-to-bound/class/static/class_FutureOr_l1_t01/02: Crash
+LanguageFeatures/Instantiate-to-bound/class/static/class_FutureOr_l1_t01/03: Crash
+LanguageFeatures/Instantiate-to-bound/class/static/class_FutureOr_l1_t01/04: Crash
+LanguageFeatures/Instantiate-to-bound/class/static/class_FutureOr_l1_t01/none: Crash
+LanguageFeatures/Instantiate-to-bound/class/static/class_FutureOr_l1_t03/01: Crash
+LanguageFeatures/Instantiate-to-bound/class/static/class_FutureOr_l1_t03/02: Crash
+LanguageFeatures/Instantiate-to-bound/class/static/class_FutureOr_l1_t03/none: Crash
+LanguageFeatures/Instantiate-to-bound/class/static/class_typedef_l1_t04/01: Crash
+LanguageFeatures/Instantiate-to-bound/class/static/class_typedef_l1_t04/02: Crash
+LanguageFeatures/Instantiate-to-bound/class/static/class_typedef_l1_t04/none: Crash
+LanguageFeatures/Instantiate-to-bound/class/static/class_typedef_l2_t04/01: Crash
+LanguageFeatures/Instantiate-to-bound/class/static/class_typedef_l2_t04/none: Crash
+LanguageFeatures/Instantiate-to-bound/class/static/class_typedef_l2_t08/01: Crash
+LanguageFeatures/Instantiate-to-bound/class/static/class_typedef_l2_t08/02: Crash
+LanguageFeatures/Instantiate-to-bound/class/static/class_typedef_l2_t08/none: Crash
+LanguageFeatures/Set-literals/disambiguating_A02_t03: Crash
+LanguageFeatures/regression/34803_t01: Crash
+LanguageFeatures/regression/34803_t02: Crash
+
+[ $runtime == vm && $system == linux && ($compiler == dartk || $compiler == dartkb) ]
+LibTest/isolate/Isolate/spawn_A06_t03: Crash
+
+[ $runtime == vm && $system == macos && ($compiler == dartk || $compiler == dartkb) ]
+LibTest/collection/ListBase/ListBase_class_A01_t02: Slow, Pass
+LibTest/collection/ListBase/ListBase_class_A01_t03: Slow, Pass
+LibTest/collection/ListMixin/ListMixin_class_A01_t02: Slow, Pass
+LibTest/collection/ListMixin/ListMixin_class_A01_t03: Slow, Pass
+LibTest/core/List/List_class_A01_t02: Slow, Pass
+LibTest/core/List/List_class_A01_t03: Slow, Pass
+
+[ $runtime != vm && ($compiler == dartk || $compiler == dartkb) ]
+Language/Classes/Constructors/Constant_Constructors/potentially_constant_expression_t01: Crash
+
+[ $compiler == dartk || $compiler == dartkb ]
+Language/Libraries_and_Scripts/Scripts/top_level_main_t01: Crash
+LibTest/isolate/SendPort/send_A01_t02: Crash
+LibTest/isolate/SendPort/send_A01_t03: Crash
+
+# It makes no sense to run any test that uses spawnURI under the simulator
+# as that would involve running CFE (the front end) in simulator mode
+# to compile the URI file specified in spawnURI code.
+# These Isolate tests that use spawnURI are hence skipped on purpose.
+[ $runtime == dart_precompiled || $runtime == vm && ($arch == simarm || $arch == simarm64) ]
+LibTest/isolate/Isolate/spawnUri*: Skip
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
new file mode 100644
index 0000000..c3ddffa
--- /dev/null
+++ b/tests/co19/co19-runtime.status
@@ -0,0 +1,13 @@
+# Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+[ $runtime != none ]
+LibTest/core/Uri/hasEmptyPath_A01_t01: RuntimeError
+LibTest/core/Uri/parse_A05_t01: RuntimeError
+
+[ $compiler != dart2js && $runtime != none && $runtime != vm && !$checked ]
+LibTest/async/Future/catchError_A03_t05: RuntimeError
+
+[ $compiler == fasta || $runtime == dart_precompiled || $runtime == vm ]
+LibTest/html/*: SkipByDesign # dart:html not supported on VM.
diff --git a/tests/co19_2/co19_2-dart2js.status b/tests/co19_2/co19_2-dart2js.status
index 2bb6211..dddded9 100644
--- a/tests/co19_2/co19_2-dart2js.status
+++ b/tests/co19_2/co19_2-dart2js.status
@@ -6,15 +6,11 @@
Language/Expressions/Null/instance_of_class_null_t01: Skip # dart:mirrors not supported https://github.com/dart-lang/co19/issues/522.
Language/Expressions/Spawning_an_Isolate/new_isolate_t01: SkipByDesign
Language/Metadata/before*: Skip # dart:mirrors not supported https://github.com/dart-lang/co19/issues/523.
-LayoutTests/*: Skip # These tests are going to be removed.
LibTest/io/*: SkipByDesign # dart:io not supported.
LibTest/isolate/*: SkipByDesign # dart:isolate not supported.
-WebPlatformTest/*: Skip # These tests are going to be removed.
[ $compiler == dart2js && $runtime == d8 ]
-LayoutTests/*: SkipByDesign # d8 is not a browser
LibTest/html/*: SkipByDesign # d8 is not a browser
-WebPlatformTest/*: SkipByDesign # d8 is not a browser
[ $compiler == dart2js && $runtime == d8 && $host_checked ]
LibTest/collection/ListBase/ListBase_class_A01_t04: Slow, Pass
diff --git a/tests/co19_2/co19_2-dartdevc.status b/tests/co19_2/co19_2-dartdevc.status
index b204630..087f30b 100644
--- a/tests/co19_2/co19_2-dartdevc.status
+++ b/tests/co19_2/co19_2-dartdevc.status
@@ -59,7 +59,6 @@
Language/Metadata/before*: Skip # dart:mirrors not supported https://github.com/dart-lang/co19/issues/523.
Language/Types/Interface_Types/subtype_t27: Skip # Times out
Language/Types/Interface_Types/subtype_t28: Skip # Times out
-LayoutTests/*: Skip # These tests are going to be removed.
LibTest/html/CanvasRenderingContext2D/addEventListener_A01_t03: Skip # Times out
LibTest/html/Element/blur_A01_t01: Skip # Times out
LibTest/html/Element/focus_A01_t01: Skip # Times out
@@ -82,4 +81,3 @@
LibTest/html/IFrameElement/onTransitionEnd_A01_t01: Skip # Times out
LibTest/io/*: SkipByDesign # dart:io not supported.
LibTest/isolate/*: SkipByDesign # dart:isolate not supported.
-WebPlatformTest/*: Skip # These tests are going to be removed.
diff --git a/tests/co19_2/co19_2-runtime.status b/tests/co19_2/co19_2-runtime.status
index acb6832..c3ddffa 100644
--- a/tests/co19_2/co19_2-runtime.status
+++ b/tests/co19_2/co19_2-runtime.status
@@ -10,6 +10,4 @@
LibTest/async/Future/catchError_A03_t05: RuntimeError
[ $compiler == fasta || $runtime == dart_precompiled || $runtime == vm ]
-LayoutTests/fast/*: SkipByDesign # DOM not supported on VM.
LibTest/html/*: SkipByDesign # dart:html not supported on VM.
-WebPlatformTest/*: SkipByDesign # dart:html not supported on VM.
diff --git a/tests/compiler/dart2js/analyses/api_allowed_nnbd.json b/tests/compiler/dart2js/analyses/api_allowed_nnbd.json
index 6d84ab9..e32d5da 100644
--- a/tests/compiler/dart2js/analyses/api_allowed_nnbd.json
+++ b/tests/compiler/dart2js/analyses/api_allowed_nnbd.json
@@ -55,7 +55,6 @@
},
"org-dartlang-sdk:///sdk_nnbd/lib/_internal/js_runtime/lib/native_typed_data.dart": {
"Dynamic invocation of '>'.": 1,
- "Dynamic invocation of '|'.": 3,
"Dynamic invocation of '>='.": 1
},
"org-dartlang-sdk:///sdk_nnbd/lib/_internal/js_runtime/lib/async_patch.dart": {
@@ -82,7 +81,6 @@
"Dynamic invocation of 'remove'.": 2,
"Dynamic update to 'dart.dom.html::_innerHtml'.": 1,
"Dynamic access of 'firstChild'.": 2,
- "Dynamic invocation of 'append'.": 1,
"Dynamic access of 'tagName'.": 2,
"Dynamic invocation of 'call'.": 2,
"Dynamic invocation of 'dart.dom.html::_initKeyboardEvent'.": 1,
@@ -100,11 +98,6 @@
"org-dartlang-sdk:///sdk_nnbd/lib/html/html_common/filtered_element_list.dart": {
"Dynamic invocation of 'remove'.": 1
},
- "org-dartlang-sdk:///sdk_nnbd/lib/indexed_db/dart2js/indexed_db_dart2js.dart": {
- "Dynamic access of 'onUpgradeNeeded'.": 1,
- "Dynamic invocation of 'listen'.": 2,
- "Dynamic access of 'onBlocked'.": 1
- },
"org-dartlang-sdk:///sdk_nnbd/lib/io/directory_impl.dart": {
"Dynamic invocation of '[]'.": 10
},
diff --git a/tests/compiler/dart2js/analyses/api_dynamic_test.dart b/tests/compiler/dart2js/analyses/api_dynamic_test.dart
index 59aa11c..53e4196 100644
--- a/tests/compiler/dart2js/analyses/api_dynamic_test.dart
+++ b/tests/compiler/dart2js/analyses/api_dynamic_test.dart
@@ -5,7 +5,7 @@
// @dart = 2.7
import 'package:async_helper/async_helper.dart';
-import '../helpers/compiler_helper.dart';
+import '../helpers/memory_compiler.dart';
import 'analysis_helper.dart';
// TODO(johnniwinther): Remove unneeded dynamic accesses from platform source
diff --git a/tests/compiler/dart2js/end_to_end/async_compiler_input_provider_test.dart b/tests/compiler/dart2js/end_to_end/async_compiler_input_provider_test.dart
index c9a6b53..1919b8a 100644
--- a/tests/compiler/dart2js/end_to_end/async_compiler_input_provider_test.dart
+++ b/tests/compiler/dart2js/end_to_end/async_compiler_input_provider_test.dart
@@ -10,9 +10,10 @@
import "package:expect/expect.dart";
import "package:async_helper/async_helper.dart";
-import 'package:_fe_analyzer_shared/src/util/filenames.dart';
import 'package:compiler/compiler.dart' as compiler;
+import '../helpers/memory_compiler.dart';
+
const Map<String, String> SOURCES = const {
"/main.dart": """
import "foo.dart";
@@ -48,9 +49,8 @@
var entrypoint = Uri.parse("file:///main.dart");
// Find the path to sdk/ in the repo relative to this script.
- Uri librariesSpec = Uri.base.resolve('sdk/lib/libraries.json');
- var platformDir =
- Uri.parse(nativeToUriPath(Platform.resolvedExecutable)).resolve('.');
+ Uri librariesSpec = sdkLibrariesSpecificationUri;
+ var platformDir = sdkPlatformBinariesPath;
asyncTest(() => compiler.compile(
entrypoint,
librariesSpec,
diff --git a/tests/compiler/dart2js/end_to_end/exit_code_test.dart b/tests/compiler/dart2js/end_to_end/exit_code_test.dart
index 4a045ee..a5182d3 100644
--- a/tests/compiler/dart2js/end_to_end/exit_code_test.dart
+++ b/tests/compiler/dart2js/end_to_end/exit_code_test.dart
@@ -31,6 +31,7 @@
import 'package:compiler/src/universe/world_impact.dart';
import 'package:compiler/src/world.dart';
import 'diagnostic_reporter_helper.dart';
+import '../helpers/memory_compiler.dart';
class TestCompiler extends CompilerImpl {
final String testMarker;
@@ -192,7 +193,8 @@
entry.compileFunc = compile;
List<String> args = new List<String>.from(options)
- ..add("--libraries-spec=${Uri.base.resolve('sdk/lib/libraries.json')}")
+ ..add("--libraries-spec=$sdkLibrariesSpecificationUri")
+ ..add("--platform-binaries=$sdkPlatformBinariesPath")
..add("tests/compiler/dart2js/end_to_end/data/exit_code_helper.dart");
Future result = entry.internalMain(args);
return result.catchError((e, s) {
diff --git a/tests/compiler/dart2js/end_to_end/library_env_test.dart b/tests/compiler/dart2js/end_to_end/library_env_test.dart
index 996bedf..ac96c89 100644
--- a/tests/compiler/dart2js/end_to_end/library_env_test.dart
+++ b/tests/compiler/dart2js/end_to_end/library_env_test.dart
@@ -8,8 +8,8 @@
/// environment variable set.
import 'dart:async';
-import 'dart:io';
+import '../helpers/memory_compiler.dart';
import '../helpers/memory_source_file_helper.dart';
import "package:async_helper/async_helper.dart";
@@ -71,8 +71,6 @@
}
}
-final platformDir = Uri.parse(Platform.resolvedExecutable).resolve('.');
-
class CustomCompiler extends CompilerImpl {
CustomCompiler(List<String> options, Map<String, String> environment)
: super(
@@ -80,9 +78,9 @@
const NullCompilerOutput(),
const DummyCompilerDiagnostics(),
CompilerOptions.parse(
- ['--platform-binaries=$platformDir']..addAll(options),
- librariesSpecificationUri:
- Uri.base.resolve("sdk/lib/libraries.json"))
+ ['--platform-binaries=$sdkPlatformBinariesPath']
+ ..addAll(options),
+ librariesSpecificationUri: sdkLibrariesSpecificationUri)
..environment = environment);
}
diff --git a/tests/compiler/dart2js/end_to_end/no_platform_test.dart b/tests/compiler/dart2js/end_to_end/no_platform_test.dart
index 5699366..ef897a9 100644
--- a/tests/compiler/dart2js/end_to_end/no_platform_test.dart
+++ b/tests/compiler/dart2js/end_to_end/no_platform_test.dart
@@ -12,6 +12,7 @@
import 'package:kernel/target/targets.dart' hide DiagnosticReporter;
import 'package:front_end/src/api_prototype/standard_file_system.dart' as fe;
import 'package:front_end/src/api_unstable/dart2js.dart' as fe;
+import '../helpers/memory_compiler.dart';
main() {
runTest(Map<fe.ExperimentalFlag, bool> experimentalFlags) async {
@@ -19,8 +20,7 @@
fe.initializeCompiler(
null,
new Dart2jsTarget('dart2js', new TargetFlags()),
- Uri.base
- .resolve('sdk/lib/libraries.json'), // librariesSpecificationUri
+ sdkLibrariesSpecificationUri,
[], // additionalDills
Uri.base.resolve('.packages'), // packagesFileUri
experimentalFlags: experimentalFlags,
@@ -37,7 +37,9 @@
}
asyncTest(() async {
- await runTest(const {});
- await runTest(const {fe.ExperimentalFlag.extensionMethods: true});
+ Map<fe.ExperimentalFlag, bool> baseFlags = {
+ fe.ExperimentalFlag.nonNullable: isDart2jsNnbd
+ };
+ await runTest(baseFlags);
});
}
diff --git a/tests/compiler/dart2js/end_to_end/output_type_test.dart b/tests/compiler/dart2js/end_to_end/output_type_test.dart
index 9a0a7b6..bd7c075 100644
--- a/tests/compiler/dart2js/end_to_end/output_type_test.dart
+++ b/tests/compiler/dart2js/end_to_end/output_type_test.dart
@@ -22,6 +22,8 @@
import 'package:compiler/src/tracer.dart' show TRACE_FILTER_PATTERN_FOR_TEST;
import 'package:expect/expect.dart';
+import '../helpers/memory_compiler.dart';
+
class TestRandomAccessFileOutputProvider implements CompilerOutput {
final RandomAccessFileOutputProvider provider;
List<String> outputs = <String>[];
@@ -44,7 +46,8 @@
Future<Null> test(List<String> arguments, List<String> expectedOutput,
{List<String> groupOutputs: const <String>[]}) async {
List<String> options = new List<String>.from(arguments)
- ..add("--libraries-spec=${Uri.base.resolve('sdk/lib/libraries.json')}");
+ ..add("--platform-binaries=$sdkPlatformBinariesPath")
+ ..add("--libraries-spec=$sdkLibrariesSpecificationUri");
print('--------------------------------------------------------------------');
print('dart2js ${options.join(' ')}');
TestRandomAccessFileOutputProvider outputProvider;
diff --git a/tests/compiler/dart2js/generic_methods/function_type_variable_test.dart b/tests/compiler/dart2js/generic_methods/function_type_variable_test.dart
index 9daeca3..56b387d 100644
--- a/tests/compiler/dart2js/generic_methods/function_type_variable_test.dart
+++ b/tests/compiler/dart2js/generic_methods/function_type_variable_test.dart
@@ -73,7 +73,6 @@
String printType(DartType type) => type.toStructuredText(
printLegacyStars: options.printLegacyStars,
- useNullSafety: options.useNullSafety,
useLegacySubtyping: options.useLegacySubtyping);
List<String> printTypes(List<DartType> types) =>
diff --git a/tests/compiler/dart2js/helpers/compiler_helper.dart b/tests/compiler/dart2js/helpers/compiler_helper.dart
index 8f4caef..5a39fad 100644
--- a/tests/compiler/dart2js/helpers/compiler_helper.dart
+++ b/tests/compiler/dart2js/helpers/compiler_helper.dart
@@ -238,6 +238,3 @@
RegExp _directivePattern = new RegExp(
// \1 \2 \3
r'''// *(present|absent): *(?:"([^"]*)"|'([^'']*)')''', multiLine: true);
-
-bool isDart2jsNnbd =
- Platform.environment['DART_CONFIGURATION'] == 'ReleaseX64NNBD';
diff --git a/tests/compiler/dart2js/helpers/d8_helper.dart b/tests/compiler/dart2js/helpers/d8_helper.dart
index 50edff3..dae47ad 100644
--- a/tests/compiler/dart2js/helpers/d8_helper.dart
+++ b/tests/compiler/dart2js/helpers/d8_helper.dart
@@ -61,7 +61,7 @@
}
List<String> d8Args = [
- 'sdk/lib/_internal/js_runtime/lib/preambles/d8.js',
+ '$sdkPath/_internal/js_runtime/lib/preambles/d8.js',
output
];
if (printSteps) print('Running: d8 ${d8Args.join(' ')}');
diff --git a/tests/compiler/dart2js/helpers/memory_compiler.dart b/tests/compiler/dart2js/helpers/memory_compiler.dart
index 761eb23..e941153 100644
--- a/tests/compiler/dart2js/helpers/memory_compiler.dart
+++ b/tests/compiler/dart2js/helpers/memory_compiler.dart
@@ -8,6 +8,7 @@
import 'dart:async';
+import 'package:_fe_analyzer_shared/src/util/filenames.dart';
import 'package:compiler/compiler.dart' show DiagnosticHandler;
import 'package:compiler/compiler_new.dart'
show CompilationResult, CompilerDiagnostics, CompilerOutput, Diagnostic;
@@ -24,6 +25,21 @@
export 'package:compiler/compiler_new.dart' show CompilationResult;
export 'diagnostic_helper.dart';
+bool isDart2jsNnbd =
+ Platform.environment['DART_CONFIGURATION'] == 'ReleaseX64NNBD';
+
+String sdkPath = isDart2jsNnbd ? 'sdk_nnbd/lib' : 'sdk/lib';
+
+String sdkLibrariesSpecificationPath = '$sdkPath/libraries.json';
+
+Uri sdkLibrariesSpecificationUri =
+ Uri.base.resolve(sdkLibrariesSpecificationPath);
+
+Uri sdkPlatformBinariesUri =
+ Uri.parse(nativeToUriPath(Platform.resolvedExecutable)).resolve('.');
+
+String sdkPlatformBinariesPath = sdkPlatformBinariesUri.toString();
+
class MultiDiagnostics implements CompilerDiagnostics {
final List<CompilerDiagnostics> diagnosticsList;
@@ -107,7 +123,7 @@
Uri librariesSpecificationUri,
Uri packageConfig}) {
retainDataForTesting = true;
- librariesSpecificationUri ??= Uri.base.resolve('sdk/lib/libraries.json');
+ librariesSpecificationUri ??= sdkLibrariesSpecificationUri;
if (packageConfig == null) {
if (Platform.packageConfig != null) {
diff --git a/tests/compiler/dart2js/model/future_or_test.dart b/tests/compiler/dart2js/model/future_or_test.dart
index 87d52be..feb5e2e 100644
--- a/tests/compiler/dart2js/model/future_or_test.dart
+++ b/tests/compiler/dart2js/model/future_or_test.dart
@@ -8,6 +8,7 @@
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/elements/types.dart';
import 'package:expect/expect.dart';
+import '../helpers/memory_compiler.dart';
import '../helpers/type_test_helper.dart';
main() {
@@ -52,6 +53,14 @@
new C().futureOrT();
}
""");
+ var options = env.compiler.options;
+
+ String typeToString(DartType type) {
+ return type.toStructuredText(
+ printLegacyStars: options.printLegacyStars,
+ useLegacySubtyping: options.useLegacySubtyping);
+ }
+
FunctionType getFunctionType(String name, String expectedType,
[ClassEntity cls]) {
FunctionType type = env.getMemberType(name, cls);
@@ -59,9 +68,9 @@
"Member $name not found${cls != null ? ' in class $cls' : ''}.");
Expect.equals(
expectedType,
- '${type}',
+ typeToString(type),
"Unexpected type for $name"
- "${cls != null ? ' in class $cls' : ''}.");
+ "${cls != null ? ' in class $cls' : ''}.");
return type;
}
@@ -70,12 +79,12 @@
FunctionType type = env.getMemberType(name, cls);
Expect.isNotNull(type,
"Member $name not found${cls != null ? ' in class $cls' : ''}.");
- DartType returnType = type.returnType;
+ DartType returnType = type.returnType.withoutNullability;
Expect.equals(
expectedType,
- '${returnType}',
+ typeToString(returnType),
"Unexpected return type for $name"
- "${cls != null ? ' in class $cls' : ''}.");
+ "${cls != null ? ' in class $cls' : ''}.");
return returnType;
}
@@ -107,13 +116,13 @@
ClassEntity C = env.getClass('C');
DartType futureT = getReturnType('futureT', 'Future<C.T>', C);
FutureOrType futureOrT = getReturnType('futureOrT', 'FutureOr<C.T>', C);
- DartType T = futureOrT.typeArgument;
+ DartType T = futureOrT.typeArgument.withoutNullability;
Expect.isTrue(futureOrT.containsTypeVariables);
futureOrT.forEachTypeVariable((t) => Expect.equals(T, t));
DartType returnVoid = getFunctionType('returnVoid', 'void Function()');
- DartType returnFutureNull =
- getFunctionType('futureOrNull', 'Future<Null> Function()');
+ DartType returnFutureNull = getFunctionType('futureOrNull',
+ isDart2jsNnbd ? 'Future<Null>? Function()' : 'Future<Null> Function()');
List<DartType> all = [
Object_,
diff --git a/tests/compiler/dart2js/model/no_such_method_forwarders_test.dart b/tests/compiler/dart2js/model/no_such_method_forwarders_test.dart
index 7535b2d..ae719aa 100644
--- a/tests/compiler/dart2js/model/no_such_method_forwarders_test.dart
+++ b/tests/compiler/dart2js/model/no_such_method_forwarders_test.dart
@@ -145,6 +145,7 @@
.parameterTypes
.first;
}
+ type = type.withoutNullability;
Expect.isTrue(type is TypeVariableType,
"Unexpected member type for $member: $type");
TypeVariableType typeVariable = type;
diff --git a/tests/compiler/dart2js/model/type_substitution_test.dart b/tests/compiler/dart2js/model/type_substitution_test.dart
index d5db6b3..64e3702 100644
--- a/tests/compiler/dart2js/model/type_substitution_test.dart
+++ b/tests/compiler/dart2js/model/type_substitution_test.dart
@@ -228,23 +228,23 @@
env.elementEnvironment,
arguments,
parameters,
- types.functionType(intType, [StringType], [], [], [], []),
- types.functionType(intType, [StringType], [], [], [], []));
+ types.functionType(intType, [StringType], [], [], {}, [], []),
+ types.functionType(intType, [StringType], [], [], {}, [], []));
testSubstitution(
types,
env.elementEnvironment,
arguments,
parameters,
- types.functionType(types.voidType(), [T, S], [], [], [], []),
+ types.functionType(types.voidType(), [T, S], [], [], {}, [], []),
types.functionType(
- types.voidType(), [intType, StringType], [], [], [], []));
+ types.voidType(), [intType, StringType], [], [], {}, [], []));
testSubstitution(
types,
env.elementEnvironment,
arguments,
parameters,
types.functionType(
- types.voidType(), [types.dynamicType()], [], [], [], []),
+ types.voidType(), [types.dynamicType()], [], [], {}, [], []),
types.functionType(
- types.voidType(), [types.dynamicType()], [], [], [], []));
+ types.voidType(), [types.dynamicType()], [], [], {}, [], []));
}
diff --git a/tests/compiler/dart2js/sourcemaps/d2js_validity_test.dart b/tests/compiler/dart2js/sourcemaps/d2js_validity_test.dart
index 0c93e47..7fea711 100644
--- a/tests/compiler/dart2js/sourcemaps/d2js_validity_test.dart
+++ b/tests/compiler/dart2js/sourcemaps/d2js_validity_test.dart
@@ -14,6 +14,8 @@
import 'helpers/source_map_validator_helper.dart';
+import '../helpers/memory_compiler.dart';
+
void main() {
String mainFile =
'tests/compiler/dart2js/sourcemaps/test_files/validator_test_file.dart';
@@ -22,7 +24,8 @@
Future<CompilationResult> result = entry.internalMain([
mainFile,
'-o${tmpDir.path}/out.js',
- '--libraries-spec=sdk/lib/libraries.json',
+ '--platform-binaries=$sdkPlatformBinariesPath',
+ '--libraries-spec=$sdkLibrariesSpecificationPath',
]);
return result.then((CompilationResult result) {
CompilerImpl compiler = result.compiler;
diff --git a/tests/compiler/dart2js/sourcemaps/deferred_d2js_validity_test.dart b/tests/compiler/dart2js/sourcemaps/deferred_d2js_validity_test.dart
index 3da203d..4b9229e 100644
--- a/tests/compiler/dart2js/sourcemaps/deferred_d2js_validity_test.dart
+++ b/tests/compiler/dart2js/sourcemaps/deferred_d2js_validity_test.dart
@@ -13,6 +13,8 @@
import 'helpers/source_map_validator_helper.dart';
+import '../helpers/memory_compiler.dart';
+
void main() {
asyncTest(() => createTempDir().then((Directory tmpDir) {
String file = 'tests/compiler/dart2js/sourcemaps/test_files/'
@@ -21,7 +23,8 @@
var result = entry.internalMain([
file,
'-o${tmpDir.path}/out.js',
- '--libraries-spec=sdk/lib/libraries.json',
+ '--platform-binaries=$sdkPlatformBinariesPath',
+ '--libraries-spec=$sdkLibrariesSpecificationPath',
]);
return result.then((CompilationResult result) {
CompilerImpl compiler = result.compiler;
diff --git a/tests/compiler/dart2js/sourcemaps/load_save_test.dart b/tests/compiler/dart2js/sourcemaps/load_save_test.dart
index 3355040..65fda6a 100644
--- a/tests/compiler/dart2js/sourcemaps/load_save_test.dart
+++ b/tests/compiler/dart2js/sourcemaps/load_save_test.dart
@@ -9,13 +9,15 @@
import 'package:source_maps/source_maps.dart';
import 'tools/load.dart';
import 'tools/save.dart';
+import '../helpers/memory_compiler.dart';
-const String SOURCEMAP = '''
+String SOURCEMAP = '''
{
"version": 3,
"file": "out.js",
"sourceRoot": "",
- "sources": ["sdk/lib/_internal/compiler/js_lib/js_primitives.dart","hello_world.dart","sdk/lib/_internal/compiler/js_lib/internal_patch.dart"],
+ "sources":
+ ["$sdkPath/_internal/compiler/js_lib/js_primitives.dart","hello_world.dart","$sdkPath/_internal/compiler/js_lib/internal_patch.dart"],
"names": ["printString","main","printToConsole"],
"mappings": "A;A;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;A;;eAoBAA;;;AAIIA;;;;AAOAA;;;AAKAA;;;AAMAA;;;GAOJA;;sC;;QC5CAC;;ICYEC;GDRFD;;;;A;A;A;;;A;;;A;A;A;A;A;A;A;;;;;;A;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;A;C;;;;;;;;;;;;;;;;;;;;;;;;;;;;A"
}''';
diff --git a/tests/compiler/dart2js/sourcemaps/stacktrace_test.dart b/tests/compiler/dart2js/sourcemaps/stacktrace_test.dart
index 6006fb4..6785cc0 100644
--- a/tests/compiler/dart2js/sourcemaps/stacktrace_test.dart
+++ b/tests/compiler/dart2js/sourcemaps/stacktrace_test.dart
@@ -15,6 +15,8 @@
import 'package:sourcemap_testing/src/stacktrace_helper.dart';
+import '../helpers/memory_compiler.dart';
+
void main(List<String> args) {
ArgParser argParser = new ArgParser(allowTrailingOptions: true);
argParser.addFlag('write-js', defaultsTo: false);
@@ -84,7 +86,8 @@
return testStackTrace(test, config, (String input, String output) async {
List<String> arguments = [
'-o$output',
- '--libraries-spec=sdk/lib/libraries.json',
+ '--platform-binaries=$sdkPlatformBinariesPath',
+ '--libraries-spec=$sdkLibrariesSpecificationPath',
'--packages=${Platform.packageConfig}',
Flags.testMode,
'--enable-experiment=extension-methods',
@@ -95,7 +98,7 @@
return compilationResult.isSuccess;
},
jsPreambles: (input, output) =>
- ['sdk/lib/_internal/js_runtime/lib/preambles/d8.js'],
+ ['$sdkPath/_internal/js_runtime/lib/preambles/d8.js'],
afterExceptions: testAfterExceptions,
beforeExceptions: beforeExceptions,
verbose: verbose,
diff --git a/tests/compiler/dart2js/sourcemaps/stepping_test.dart b/tests/compiler/dart2js/sourcemaps/stepping_test.dart
index 311d462..f5911da 100644
--- a/tests/compiler/dart2js/sourcemaps/stepping_test.dart
+++ b/tests/compiler/dart2js/sourcemaps/stepping_test.dart
@@ -16,6 +16,8 @@
import 'package:expect/expect.dart';
import 'package:sourcemap_testing/src/stepping_helper.dart';
+import '../helpers/memory_compiler.dart';
+
void main(List<String> args) {
ArgParser argParser = new ArgParser(allowTrailingOptions: true);
argParser.addFlag('debug', abbr: 'd', defaultsTo: false);
@@ -77,7 +79,7 @@
CompilationResult compilationResult = await entry.internalMain(arguments);
Expect.isTrue(compilationResult.isSuccess);
List<String> scriptD8Command = [
- 'sdk/lib/_internal/js_runtime/lib/preambles/d8.js',
+ '$sdkPath/_internal/js_runtime/lib/preambles/d8.js',
outputFile
];
ProcessResult result = runD8AndStep(dir.path, annotatedCode, scriptD8Command);
diff --git a/tests/compiler/dart2js_extra/rti/subtype_test.dart b/tests/compiler/dart2js_extra/rti/subtype_test.dart
index 0d34f3f..3ffea446 100644
--- a/tests/compiler/dart2js_extra/rti/subtype_test.dart
+++ b/tests/compiler/dart2js_extra/rti/subtype_test.dart
@@ -39,6 +39,7 @@
testInterfaces();
testTopTypes();
testNull();
+ testBottom();
testFutureOr();
testFunctions();
testGenericFunctions();
@@ -80,6 +81,11 @@
equivalent(nullName, nullName);
}
+void testBottom() {
+ String never = '0&';
+ equivalent(nullName, never); // This test is run with legacy subtyping
+}
+
void testFutureOr() {
strictSubtype('$futureName<int>', '$futureName<num>');
strictSubtype('int', 'int/');
diff --git a/tests/corelib/cast_errors_test.dart b/tests/corelib/cast_errors_test.dart
new file mode 100644
index 0000000..0d75f28
--- /dev/null
+++ b/tests/corelib/cast_errors_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:collection";
+import 'cast_helper.dart';
+
+void main() {
+ testSetDowncast();
+ testMapDowncast();
+}
+
+void testSetDowncast() {
+ var setEls = new Set<C?>.from(elements);
+ var dSet = Set.castFrom<C?, D?>(setEls);
+
+ var newC = new C();
+ dSet.add(newC);
+ // ^^^^
+ // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ // [cfe] The argument type 'C' can't be assigned to the parameter type 'D?'.
+}
+
+void testMapDowncast() {
+ var map = new Map.fromIterables(elements, elements);
+ var dMap = Map.castFrom<C?, C?, D?, D?>(map);
+
+ dMap[c] = d;
+ // ^
+ // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ // [cfe] A value of type 'C' can't be assigned to a variable of type 'D?'.
+ dMap[d] = c;
+ // ^
+ // [analyzer] STATIC_TYPE_WARNING.INVALID_ASSIGNMENT
+ // [cfe] A value of type 'C' can't be assigned to a variable of type 'D?'.
+}
diff --git a/tests/corelib/cast_helper.dart b/tests/corelib/cast_helper.dart
new file mode 100644
index 0000000..d0537da
--- /dev/null
+++ b/tests/corelib/cast_helper.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+final elements = <C?>[c, d, e, f, null];
+
+class C {}
+
+class D extends C {}
+
+class E extends C {}
+
+class F implements D, E {}
+
+final c = C();
+final d = D();
+final e = E();
+final f = F();
diff --git a/tests/corelib/cast_iterable_test.dart b/tests/corelib/cast_iterable_test.dart
new file mode 100644
index 0000000..35ce89e
--- /dev/null
+++ b/tests/corelib/cast_iterable_test.dart
@@ -0,0 +1,68 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:collection";
+import "package:expect/expect.dart";
+import 'cast_helper.dart';
+
+void main() {
+ testDowncastDirectAccess();
+ testDowncastNoDirectAccess();
+ testDowncastUntouchableElements();
+ testUpcast();
+}
+
+void testDowncastDirectAccess() {
+ var iterable = new Iterable<C?>.generate(elements.length, (n) => elements[n]);
+
+ // An iterable that (likely) can do direct access.
+ var dIterable = Iterable.castFrom<C?, D?>(iterable);
+
+ Expect.throws(() => dIterable.first);
+ Expect.equals(d, dIterable.elementAt(1));
+ Expect.throws(() => dIterable.elementAt(2)); // E is not D?
+ Expect.equals(f, dIterable.skip(3).first); // Skip does not access element.
+ Expect.equals(null, dIterable.skip(3).elementAt(1));
+
+ Expect.throws(() => dIterable.toList());
+}
+
+void testDowncastNoDirectAccess() {
+ var iterable = new Iterable<C?>.generate(elements.length, (n) => elements[n]);
+
+ // An iterable that cannot do direct access.
+ var dIterable = Iterable.castFrom<C?, D?>(iterable.where((_) => true));
+
+ Expect.throws(() => dIterable.first);
+ Expect.equals(d, dIterable.elementAt(1));
+ // E is not D?.
+ Expect.throws(() => dIterable.elementAt(2));
+ Expect.equals(f, dIterable.skip(3).first); // Skip does not access element.
+ Expect.equals(null, dIterable.skip(3).elementAt(1));
+
+ Expect.throws(() => dIterable.toList());
+}
+
+void testDowncastUntouchableElements() {
+ // Iterable that definitely won't survive accessing element 3.
+ var iterable = new Iterable<C?>.generate(
+ elements.length, (n) => n == 3 ? throw "untouchable" : elements[n]);
+ var dIterable = Iterable.castFrom<C?, D?>(iterable);
+
+ Expect.throws(() => dIterable.first);
+ Expect.equals(d, dIterable.elementAt(1));
+ Expect.throws(() => dIterable.elementAt(3));
+ // Skip does not access element.
+ Expect.equals(null, dIterable.skip(4).first);
+ Expect.equals(null, dIterable.skip(3).elementAt(1));
+
+ Expect.throws(() => dIterable.toList());
+}
+
+void testUpcast() {
+ var iterable = new Iterable<C?>.generate(elements.length, (n) => elements[n]);
+
+ var objectIterable = Iterable.castFrom<C?, Object?>(iterable);
+ Expect.listEquals(elements, objectIterable.toList());
+}
diff --git a/tests/corelib/cast_list_test.dart b/tests/corelib/cast_list_test.dart
new file mode 100644
index 0000000..c214685
--- /dev/null
+++ b/tests/corelib/cast_list_test.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:collection";
+import "package:expect/expect.dart";
+import 'cast_helper.dart';
+
+void main() {
+ testDowncast();
+ testUpcast();
+ testRegression();
+}
+
+void testDowncast() {
+ var list = new List<C?>.from(elements);
+ var dList = List.castFrom<C?, D?>(list);
+
+ Expect.throws(() => dList.first); // C is not D?.
+ Expect.equals(d, dList[1]);
+ Expect.throws(() => dList[2]); // E is not D?.
+ Expect.equals(f, dList[3]);
+ Expect.equals(null, dList.last);
+
+ Expect.throws(() => dList.toList());
+
+ // Setting works.
+ dList[2] = d;
+ Expect.equals(d, dList[2]);
+}
+
+void testUpcast() {
+ var list = new List<C?>.from(elements);
+ var objectList = List.castFrom<C?, Object?>(list);
+ Expect.listEquals(elements, objectList);
+ Expect.throws(() => objectList[2] = new Object()); // Cannot set non-C.
+ Expect.listEquals(elements, objectList);
+}
+
+void testRegression() {
+ var numList = <num>[4, 3, 2, 1];
+ var intList = numList.cast<int>();
+ intList.sort(null);
+ Expect.listEquals([1, 2, 3, 4], numList);
+ Expect.listEquals([1, 2, 3, 4], intList);
+}
diff --git a/tests/corelib/cast_map_test.dart b/tests/corelib/cast_map_test.dart
new file mode 100644
index 0000000..a827b0c
--- /dev/null
+++ b/tests/corelib/cast_map_test.dart
@@ -0,0 +1,57 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:collection";
+import "package:expect/expect.dart";
+import 'cast_helper.dart';
+
+void main() {
+ testDowncast();
+ testUpcast();
+}
+
+void testDowncast() {
+ var map = new Map.fromIterables(elements, elements);
+ var dMap = Map.castFrom<C?, C?, D?, D?>(map);
+
+ Expect.isTrue(dMap is Map<D?, D?>);
+
+ Expect.equals(null, dMap[new C()]);
+ Expect.throws(() => dMap[c]); // C is not D?.
+ Expect.isTrue(dMap.containsKey(c)); // containsKey should not be typed.
+ Expect.equals(d, dMap[d]);
+ Expect.throws(() => dMap[e]); // E is not D?.
+ Expect.isTrue(dMap.containsKey(null));
+ Expect.equals(null, dMap[null]);
+
+ Expect.equals(5, dMap.length);
+ Expect.throws(() => dMap.remove(c)); // Removes key but fails to return value.
+ Expect.equals(4, dMap.length);
+ Expect.equals(null, dMap[c]);
+
+ // Test keys and values.
+ Expect.isTrue(dMap.keys is Iterable<D?>);
+ Expect.isTrue(dMap.values is Iterable<D?>);
+ Expect.throws(() => dMap.keys.toList());
+ Expect.throws(() => dMap.values.toList());
+}
+
+void testUpcast() {
+ var map = new Map.fromIterables(elements, elements);
+ var objectMap = Map.castFrom<C?, C?, Object?, Object?>(map);
+
+ Expect.equals(5, objectMap.length);
+ Expect.equals(c, objectMap[c]);
+ Expect.isTrue(objectMap.containsKey(c));
+ Expect.equals(c, objectMap.remove(c));
+ Expect.equals(4, objectMap.length);
+
+ // Test keys and values.
+ Expect.isTrue(objectMap.keys is Iterable<Object?>);
+ Expect.isTrue(objectMap.values is Iterable<Object?>);
+ var expected = new List<Object?>.from(elements);
+ expected.remove(c);
+ Expect.listEquals(expected, objectMap.keys.toList());
+ Expect.listEquals(expected, objectMap.values.toList());
+}
diff --git a/tests/corelib/cast_set_test.dart b/tests/corelib/cast_set_test.dart
new file mode 100644
index 0000000..d33ccd73
--- /dev/null
+++ b/tests/corelib/cast_set_test.dart
@@ -0,0 +1,71 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:collection";
+import "package:expect/expect.dart";
+import 'cast_helper.dart';
+
+void main() {
+ testOrder();
+ testDowncast();
+ testUpcast();
+ testNewSet();
+}
+
+void testOrder() {
+ var setEls = new Set<C?>.from(elements); // Linked HashSet.
+ Expect.listEquals(elements, setEls.toList()); // Preserves order.
+}
+
+void testDowncast() {
+ var setEls = new Set<C?>.from(elements);
+ var dSet = Set.castFrom<C?, D?>(setEls);
+
+ // Preserves order.
+ Expect.throws(() => dSet.first); // C is not D?.
+ Expect.equals(d, dSet.elementAt(1));
+ Expect.throws(() => dSet.elementAt(2)); // E is not D?.
+ Expect.equals(f, dSet.elementAt(3));
+ Expect.equals(null, dSet.elementAt(4));
+
+ Expect.throws(() => dSet.toList());
+
+ // Contains should not be typed.
+ var newC = new C();
+ Expect.isFalse(dSet.contains(newC));
+ Expect.isTrue(dSet.contains(c));
+
+ // Remove and length should not be typed.
+ Expect.equals(5, dSet.length);
+ dSet.remove(c); // Success, no type checks.
+ Expect.equals(4, dSet.length);
+}
+
+void testUpcast() {
+ var setEls = new Set<C?>.from(elements);
+ var objectSet = Set.castFrom<C?, Object?>(setEls);
+
+ Expect.listEquals(elements, objectSet.toList());
+
+ var newObject = new Object();
+ Expect.throws(() => objectSet.add(newObject));
+ Expect.isFalse(objectSet.contains(newObject));
+
+ var toSet = objectSet.toSet();
+ Expect.isTrue(toSet is LinkedHashSet<Object?>);
+ Expect.isFalse(toSet is LinkedHashSet<C?>);
+}
+
+void testNewSet() {
+ // Specified custom newSet as empty HashSet.
+ var setEls = new Set<C?>.from(elements);
+ var customNewSet;
+ var objectSet2 = Set.castFrom<C?, Object?>(setEls,
+ newSet: <T>() => customNewSet = new HashSet<T>());
+
+ var customToSet = objectSet2.toSet();
+ Expect.isTrue(customToSet is HashSet<Object?>);
+ Expect.isFalse(customToSet is HashSet<C?>);
+ Expect.identical(customToSet, customNewSet);
+}
diff --git a/tests/corelib/cast_strong_test.dart b/tests/corelib/cast_strong_test.dart
new file mode 100644
index 0000000..b935ac3
--- /dev/null
+++ b/tests/corelib/cast_strong_test.dart
@@ -0,0 +1,106 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Requirements=nnbd-strong
+
+import "dart:collection";
+import "package:expect/expect.dart";
+import 'cast_helper.dart';
+
+void main() {
+ testIterable();
+ testList();
+ testMap();
+ testSet();
+}
+
+testIterable() {
+ var iterable = new Iterable<C?>.generate(elements.length, (n) => elements[n]);
+ var iterableNonNull = Iterable.castFrom<C?, C>(iterable);
+ // Downcast non-nullable.
+
+ // An iterable that (likely) can do direct access.
+ var dIterableDirect = Iterable.castFrom<C, D>(iterableNonNull);
+ Expect.equals(d, dIterableDirect.elementAt(1));
+ // null is not D.
+ Expect.throws(() => dIterableDirect.skip(3).elementAt(1));
+
+ // An iterable that cannot do direct access.
+ var dIterableNonDirect =
+ Iterable.castFrom<C, D>(iterableNonNull.where((_) => true));
+ Expect.equals(d, dIterableNonDirect.elementAt(1));
+ // null is not D.
+ Expect.throws(() => dIterableNonDirect.skip(3).elementAt(1));
+
+ // Iterable that definitely won't survive accessing element 3.
+ var iterableLimited = new Iterable<C?>.generate(
+ elements.length, (n) => n == 3 ? throw "untouchable" : elements[n]);
+ var iterableLimitedNonNull = Iterable.castFrom<C?, C>(iterableLimited);
+ var dIterableLimited = Iterable.castFrom<C, D>(iterableLimitedNonNull);
+ Expect.equals(d, dIterableLimited.elementAt(1));
+ // null is not D.
+ Expect.throws(() => dIterableLimited.skip(3).elementAt(1));
+
+ // Upcast non-nullable.
+ var objectIterable = Iterable.castFrom<C, Object>(iterableNonNull);
+ // null is not Object.
+ Expect.throws(() => objectIterable.skip(3).elementAt(1));
+}
+
+testList() {
+ var list = new List<C?>.from(elements);
+ var listNonNull = List.castFrom<C?, C>(list);
+
+ // Downcast non-nullable.
+ var dList = List.castFrom<C, D>(listNonNull);
+ Expect.equals(d, dList[1]);
+ Expect.throws(() => dList.last); // null is not D.
+
+ // Upcast non-nullable.
+ var objectList = List.castFrom<C, Object>(listNonNull);
+ Expect.throws(() => objectList.last); // null is not Object.
+}
+
+testMap() {
+ var map = new Map.fromIterables(elements, elements);
+ var mapNonNull = Map.castFrom<C?, C?, C, C>(map);
+
+ // Downcast non-nullable.
+ var dMap = Map.castFrom<C, C, D, D>(mapNonNull);
+ Expect.equals(d, dMap[d]);
+ Expect.isTrue(dMap.containsKey(null));
+ Expect.equals(null, dMap[null]);
+
+ // Test keys and values
+ Expect.isTrue(dMap.keys is Iterable<D>);
+ Expect.isTrue(dMap.values is Iterable<D>);
+ Expect.throws(() => dMap.keys.toList());
+ Expect.throws(() => dMap.values.toList());
+
+ // Upcast non-nullable.
+ var objectMap = Map.castFrom<C, C, Object, Object>(mapNonNull);
+ Expect.isTrue(objectMap.containsKey(null));
+ Expect.equals(null, objectMap[null]);
+
+ // Test keys and values
+ Expect.isTrue(objectMap.keys is Iterable<Object>);
+ Expect.isTrue(objectMap.values is Iterable<Object>);
+ // null is not Object.
+ Expect.throws(() => objectMap.keys.toList());
+ Expect.throws(() => objectMap.values.toList());
+}
+
+testSet() {
+ var setEls = new Set<C?>.from(elements);
+ var setNonNull = Set.castFrom<C?, C>(setEls);
+
+ // Downcast non-nullable.
+ var dSet = Set.castFrom<C, D>(setNonNull);
+ Expect.equals(d, dSet.elementAt(1));
+ Expect.throws(() => dSet.last); // null is not D.
+
+ // Upcast non-nullable.
+ var objectSet = Set.castFrom<C, Object>(setNonNull);
+ Expect.throws(() => objectSet.last); // null is not Object.
+}
diff --git a/tests/corelib/cast_test.dart b/tests/corelib/cast_test.dart
deleted file mode 100644
index 7f17351..0000000
--- a/tests/corelib/cast_test.dart
+++ /dev/null
@@ -1,189 +0,0 @@
-// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "dart:collection";
-import "dart:typed_data";
-import "package:expect/expect.dart";
-
-// TODO(rnystrom): Not migrated to NNBD yet.
-// See https://github.com/dart-lang/sdk/issues/39517.
-
-void main() {
- testIterable();
- testList();
-}
-
-final elements = <C>[c, d, e, f, null];
-
-void testIterable() {
- var iterable = new Iterable<C>.generate(elements.length, (n) => elements[n]);
- // Down-cast
- {
- // An iterable that (likely) can do direct access.
- var dIterable = Iterable.castFrom<C, D>(iterable);
-
- Expect.throws(() => dIterable.first, null, "1.first");
- Expect.equals(d, dIterable.elementAt(1));
- Expect.throws(() => dIterable.elementAt(2), null, "1.2"); // E is not D.
- Expect.equals(f, dIterable.skip(3).first); // Skip does not access element.
- Expect.equals(null, dIterable.skip(3).elementAt(1));
-
- Expect.throws(() => dIterable.toList(), null, "1.toList");
- }
-
- {
- // An iterable that cannot do direct access.
- var dIterable2 = Iterable.castFrom<C, D>(iterable.where((_) => true));
-
- Expect.throws(() => dIterable2.first, null, "2.first");
- Expect.equals(d, dIterable2.elementAt(1));
- Expect.throws(() => dIterable2.elementAt(2), null, "2.2"); // E is not D.
- Expect.equals(f, dIterable2.skip(3).first); // Skip does not access element.
- Expect.equals(null, dIterable2.skip(3).elementAt(1));
-
- Expect.throws(() => dIterable2.toList(), null, "2.toList");
- }
-
- {
- // Iterable that definitely won't survive accessing element 2.
- var iterable3 = new Iterable<C>.generate(
- elements.length, (n) => n == 3 ? throw "untouchable" : elements[n]);
- var dIterable3 = Iterable.castFrom<C, D>(iterable3);
-
- Expect.throws(() => dIterable3.first, null, "3.first");
- Expect.equals(d, dIterable3.elementAt(1));
- Expect.throws(() => dIterable3.elementAt(3), null, "3.3");
- // Skip does not access element.
- Expect.equals(null, dIterable3.skip(4).first);
- Expect.equals(null, dIterable3.skip(3).elementAt(1));
-
- Expect.throws(() => dIterable3.toList(), null, "3.toList");
- }
-
- // Up-cast.
- {
- var oIterable4 = Iterable.castFrom<C, Object>(iterable);
- Expect.listEquals(elements, oIterable4.toList());
- }
-}
-
-void testList() {
- // Down-cast.
- var list = new List<C>.from(elements);
- var dList = List.castFrom<C, D>(list);
-
- Expect.throws(() => dList.first); // C is not D.
- Expect.equals(d, dList[1]);
- Expect.throws(() => dList[2]); // E is not D.
- Expect.equals(f, dList[3]);
- Expect.equals(null, dList.last);
-
- Expect.throws(() => dList.toList());
-
- dList[2] = d;
- Expect.equals(d, dList[2]); // Setting works.
-
- // Up-cast.
- var list2 = new List<C>.from(elements);
- var dList2 = List.castFrom<C, Object>(list2);
- Expect.listEquals(elements, dList2);
- Expect.throws(() => dList2[2] = new Object()); // Cannot set non-C.
- Expect.listEquals(elements, dList2);
-
- // Regression test.
- var list3 = <num>[4, 3, 2, 1];
- var dList3 = list3.cast<int>();
- dList3.sort(null);
- Expect.listEquals([1, 2, 3, 4], list3);
-}
-
-void testSet() {
- var set = new Set<C>.from(elements); // Linked HashSet.
- Expect.listEquals(elements, set.toList()); // Preserves order.
-
- var dSet = Set.castFrom<C, D>(set);
-
- // Preserves order.
- Expect.throws(() => dSet.first); // C is not D.
- Expect.equals(d, dSet.elementAt(1));
- Expect.throws(() => dSet.elementAt(2)); // E is not D.
-
- Expect.throws(() => dSet.toList());
-
- // Contains is not typed.
- var newC = new C();
- Expect.isFalse(dSet.contains(newC));
- dSet.add(newC);
- Expect.isTrue(dSet.contains(newC));
-
- Expect.equals(5, dSet.length);
- dSet.remove(newC);
- Expect.equals(5, dSet.length);
- dSet.remove(c); // Success, no type checks.
- Expect.equals(4, dSet.length);
-
- // Up-cast
- var set2 = new Set<C>.from(elements);
- var dSet2 = Set.castFrom<C, Object>(set2);
-
- var newObject = new Object();
- Expect.throws(() => dSet2.add(newObject));
- Expect.isFalse(dSet.contains(newObject));
-
- var toSet2 = dSet2.toSet();
- Expect.isTrue(toSet2 is LinkedHashSet<Object>);
- Expect.isTrue(toSet2 is! LinkedHashSet<C>);
-
- // Custom emptySet.
-
- var set3 = new Set<C>.from(elements);
- var dSet3 = Set.castFrom<C, Object>(set3, newSet: <T>() => new HashSet<T>());
-
- var toSet3 = dSet3.toSet();
- Expect.isTrue(toSet3 is HashSet<Object>);
- Expect.isTrue(toSet3 is HashSet<C>);
- Expect.isTrue(toSet3 is! LinkedHashSet<Object>);
-}
-
-void testMap() {
- var map = new Map.fromIterables(elements, elements);
-
- var dMap = Map.castFrom<C, C, D, D>(map);
-
- Expect.isTrue(dMap is Map<D, D>);
-
- Expect.equals(null, dMap[new C()]);
- Expect.throws(() => dMap[c]);
- Expect.isTrue(dMap.containsKey(c));
- Expect.equals(d, dMap[d]);
- Expect.throws(() => dMap[e]);
- Expect.equals(null, dMap[null]);
-
- Expect.equals(5, dMap.length);
- dMap.remove(c); // Success, no type checks along the way.
- Expect.equals(4, dMap.length);
- Expect.equals(null, dMap[c]);
-
- Expect.throws(() => dMap[c] = d);
- Expect.throws(() => dMap[d] = c);
- Expect.equals(4, dMap.length);
-
- Expect.isTrue(dMap.keys is Iterable<D>);
- Expect.isTrue(dMap.values is Iterable<D>);
- Expect.throws(() => dMap.keys.toList());
- Expect.throws(() => dMap.values.toList());
-}
-
-class C {}
-
-class D extends C {}
-
-class E extends C {}
-
-class F implements D, E {}
-
-final c = new C();
-final d = new D();
-final e = new E();
-final f = new F();
diff --git a/tests/corelib/cast_weak_test.dart b/tests/corelib/cast_weak_test.dart
new file mode 100644
index 0000000..72b1231
--- /dev/null
+++ b/tests/corelib/cast_weak_test.dart
@@ -0,0 +1,101 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Requirements=nnbd-weak
+
+import "dart:collection";
+import "package:expect/expect.dart";
+import 'cast_helper.dart';
+
+void main() {
+ testIterable();
+ testList();
+ testMap();
+ testSet();
+}
+
+testIterable() {
+ var iterable = new Iterable<C?>.generate(elements.length, (n) => elements[n]);
+ var iterableNonNull = Iterable.castFrom<C?, C>(iterable);
+ // Downcast non-nullable.
+
+ // An iterable that (likely) can do direct access.
+ var dIterableDirect = Iterable.castFrom<C, D>(iterableNonNull);
+ Expect.equals(d, dIterableDirect.elementAt(1));
+ Expect.equals(null, dIterableDirect.skip(3).elementAt(1));
+
+ // An iterable that cannot do direct access.
+ var dIterableNonDirect =
+ Iterable.castFrom<C, D>(iterableNonNull.where((_) => true));
+ Expect.equals(d, dIterableNonDirect.elementAt(1));
+ Expect.equals(null, dIterableNonDirect.skip(3).elementAt(1));
+
+ // Iterable that definitely won't survive accessing element 3.
+ var iterableLimited = new Iterable<C?>.generate(
+ elements.length, (n) => n == 3 ? throw "untouchable" : elements[n]);
+ var iterableLimitedNonNull = Iterable.castFrom<C?, C>(iterableLimited);
+ var dIterableLimited = Iterable.castFrom<C, D>(iterableLimitedNonNull);
+ Expect.equals(d, dIterableLimited.elementAt(1));
+ Expect.equals(null, dIterableLimited.skip(3).elementAt(1));
+
+ // Upcast non-nullable.
+ var objectIterable = Iterable.castFrom<C, Object>(iterableNonNull);
+ Expect.equals(null, objectIterable.skip(3).elementAt(1));
+}
+
+testList() {
+ var list = new List<C?>.from(elements);
+ var listNonNull = List.castFrom<C?, C>(list);
+
+ // Downcast non-nullable.
+ var dList = List.castFrom<C, D>(listNonNull);
+ Expect.equals(d, dList[1]);
+ Expect.equals(null, dList.last);
+
+ // Upcast non-nullable.
+ var objectList = List.castFrom<C, Object>(listNonNull);
+ Expect.equals(null, objectList.last);
+}
+
+testMap() {
+ var map = new Map.fromIterables(elements, elements);
+ var mapNonNull = Map.castFrom<C?, C?, C, C>(map);
+
+ // Downcast non-nullable.
+ var dMap = Map.castFrom<C, C, D, D>(mapNonNull);
+ Expect.equals(d, dMap[d]);
+ Expect.isTrue(dMap.containsKey(null));
+ Expect.equals(null, dMap[null]);
+
+ // Test keys and values
+ Expect.isTrue(dMap.keys is Iterable<D>);
+ Expect.isTrue(dMap.values is Iterable<D>);
+ Expect.throws(() => dMap.keys.toList());
+ Expect.throws(() => dMap.values.toList());
+
+ // Upcast non-nullable.
+ var objectMap = Map.castFrom<C, C, Object, Object>(mapNonNull);
+ Expect.isTrue(objectMap.containsKey(null));
+ Expect.equals(null, objectMap[null]);
+
+ // Test keys and values
+ Expect.isTrue(objectMap.keys is Iterable<Object>);
+ Expect.isTrue(objectMap.values is Iterable<Object>);
+ var expectedValues = new List<Object>.from(elements);
+ Expect.listEquals(expectedValues, objectMap.values.toList());
+}
+
+testSet() {
+ var setEls = new Set<C?>.from(elements);
+ var setNonNull = Set.castFrom<C?, C>(setEls);
+
+ // Downcast non-nullable.
+ var dSet = Set.castFrom<C, D>(setNonNull);
+ Expect.equals(d, dSet.elementAt(1));
+ Expect.equals(null, dSet.last);
+
+ // Upcast non-nullable.
+ var objectSet = Set.castFrom<C, Object>(setNonNull);
+ Expect.equals(null, objectSet.last);
+}
diff --git a/tests/corelib_2/cast_helper.dart b/tests/corelib_2/cast_helper.dart
new file mode 100644
index 0000000..6e2d76a
--- /dev/null
+++ b/tests/corelib_2/cast_helper.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+final elements = <C>[c, d, e, f, null];
+
+class C {}
+
+class D extends C {}
+
+class E extends C {}
+
+class F implements D, E {}
+
+final c = C();
+final d = D();
+final e = E();
+final f = F();
diff --git a/tests/corelib_2/cast_iterable_test.dart b/tests/corelib_2/cast_iterable_test.dart
new file mode 100644
index 0000000..19836f0
--- /dev/null
+++ b/tests/corelib_2/cast_iterable_test.dart
@@ -0,0 +1,68 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:collection";
+import "package:expect/expect.dart";
+import 'cast_helper.dart';
+
+void main() {
+ testDowncastDirectAccess();
+ testDowncastNoDirectAccess();
+ testDowncastUntouchableElements();
+ testUpcast();
+}
+
+void testDowncastDirectAccess() {
+ var iterable = new Iterable<C>.generate(elements.length, (n) => elements[n]);
+
+ // An iterable that (likely) can do direct access.
+ var dIterable = Iterable.castFrom<C, D>(iterable);
+
+ Expect.throws(() => dIterable.first, null, "direct.first");
+ Expect.equals(d, dIterable.elementAt(1));
+ Expect.throws(() => dIterable.elementAt(2), null, "direct.2"); // E is not D.
+ Expect.equals(f, dIterable.skip(3).first); // Skip does not access element.
+ Expect.equals(null, dIterable.skip(3).elementAt(1));
+
+ Expect.throws(() => dIterable.toList(), null, "direct.toList");
+}
+
+void testDowncastNoDirectAccess() {
+ var iterable = new Iterable<C>.generate(elements.length, (n) => elements[n]);
+
+ // An iterable that cannot do direct access.
+ var dIterable = Iterable.castFrom<C, D>(iterable.where((_) => true));
+
+ Expect.throws(() => dIterable.first, null, "nonDirect.first");
+ Expect.equals(d, dIterable.elementAt(1));
+ // E is not D.
+ Expect.throws(() => dIterable.elementAt(2), null, "nonDirect.2");
+ Expect.equals(f, dIterable.skip(3).first); // Skip does not access element.
+ Expect.equals(null, dIterable.skip(3).elementAt(1));
+
+ Expect.throws(() => dIterable.toList(), null, "nonDirect.toList");
+}
+
+void testDowncastUntouchableElements() {
+ // Iterable that definitely won't survive accessing element 3.
+ var iterable = new Iterable<C>.generate(
+ elements.length, (n) => n == 3 ? throw "untouchable" : elements[n]);
+ var dIterable = Iterable.castFrom<C, D>(iterable);
+
+ Expect.throws(() => dIterable.first, null, "untouchable.first");
+ Expect.equals(d, dIterable.elementAt(1));
+ Expect.throws(() => dIterable.elementAt(3), null, "untouchable.3");
+ // Skip does not access element.
+ Expect.equals(null, dIterable.skip(4).first);
+ Expect.equals(null, dIterable.skip(3).elementAt(1));
+
+ Expect.throws(() => dIterable.toList(), null, "untouchable.toList");
+}
+
+void testUpcast() {
+ var iterable = new Iterable<C>.generate(elements.length, (n) => elements[n]);
+
+ var objectIterable = Iterable.castFrom<C, Object>(iterable);
+ Expect.listEquals(elements, objectIterable.toList());
+}
diff --git a/tests/corelib_2/cast_list_test.dart b/tests/corelib_2/cast_list_test.dart
new file mode 100644
index 0000000..75f3072
--- /dev/null
+++ b/tests/corelib_2/cast_list_test.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:collection";
+import "package:expect/expect.dart";
+import 'cast_helper.dart';
+
+void main() {
+ testDowncast();
+ testUpcast();
+ testRegression();
+}
+
+void testDowncast() {
+ var list = new List<C>.from(elements);
+ var dList = List.castFrom<C, D>(list);
+
+ Expect.throws(() => dList.first); // C is not D.
+ Expect.equals(d, dList[1]);
+ Expect.throws(() => dList[2]); // E is not D.
+ Expect.equals(f, dList[3]);
+ Expect.equals(null, dList.last);
+
+ Expect.throws(() => dList.toList());
+
+ // Setting works.
+ dList[2] = d;
+ Expect.equals(d, dList[2]);
+}
+
+void testUpcast() {
+ var list2 = new List<C>.from(elements);
+ var dList2 = List.castFrom<C, Object>(list2);
+ Expect.listEquals(elements, dList2);
+ Expect.throws(() => dList2[2] = new Object()); // Cannot set non-C.
+ Expect.listEquals(elements, dList2);
+}
+
+void testRegression() {
+ var numList = <num>[4, 3, 2, 1];
+ var intList = numList.cast<int>();
+ intList.sort(null);
+ Expect.listEquals([1, 2, 3, 4], numList);
+ Expect.listEquals([1, 2, 3, 4], intList);
+}
diff --git a/tests/corelib_2/cast_map_test.dart b/tests/corelib_2/cast_map_test.dart
new file mode 100644
index 0000000..123bd1e
--- /dev/null
+++ b/tests/corelib_2/cast_map_test.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:collection";
+import "package:expect/expect.dart";
+import 'cast_helper.dart';
+
+void main() {
+ testDowncast();
+ testUpcast();
+}
+
+void testDowncast() {
+ var map = new Map.fromIterables(elements, elements);
+ var dMap = Map.castFrom<C, C, D, D>(map);
+
+ Expect.isTrue(dMap is Map<D, D>);
+
+ Expect.equals(null, dMap[new C()]);
+ Expect.throws(() => dMap[c]); // C is not D.
+ Expect.isTrue(dMap.containsKey(c)); // containsKey should not be typed.
+ Expect.equals(d, dMap[d]);
+ Expect.throws(() => dMap[e]); // E is not D.
+ Expect.isTrue(dMap.containsKey(null));
+ Expect.equals(null, dMap[null]);
+
+ Expect.equals(5, dMap.length);
+ Expect.throws(() => dMap.remove(c)); // Removes key but fails to return value.
+ Expect.equals(4, dMap.length);
+ Expect.equals(null, dMap[c]);
+
+ // Runtime errors when assigning or accessing a C.
+ Expect.throws(() => dMap[c] = d);
+ Expect.throws(() => dMap[d] = c);
+ Expect.equals(4, dMap.length);
+
+ // Test keys and values.
+ Expect.isTrue(dMap.keys is Iterable<D>);
+ Expect.isTrue(dMap.values is Iterable<D>);
+ Expect.throws(() => dMap.keys.toList());
+ Expect.throws(() => dMap.values.toList());
+}
+
+void testUpcast() {
+ var map = new Map.fromIterables(elements, elements);
+ var objectMap = Map.castFrom<C, C, Object, Object>(map);
+
+ Expect.equals(5, objectMap.length);
+ Expect.equals(c, objectMap[c]);
+ Expect.isTrue(objectMap.containsKey(c));
+ Expect.equals(c, objectMap.remove(c));
+ Expect.equals(4, objectMap.length);
+
+ // Test keys and values.
+ Expect.isTrue(objectMap.keys is Iterable<Object>);
+ Expect.isTrue(objectMap.values is Iterable<Object>);
+ var expected = new List<Object>.from(elements);
+ expected.remove(c);
+ Expect.listEquals(expected, objectMap.keys.toList());
+ Expect.listEquals(expected, objectMap.values.toList());
+}
diff --git a/tests/corelib_2/cast_set_test.dart b/tests/corelib_2/cast_set_test.dart
new file mode 100644
index 0000000..8b8dc71
--- /dev/null
+++ b/tests/corelib_2/cast_set_test.dart
@@ -0,0 +1,73 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:collection";
+import "package:expect/expect.dart";
+import 'cast_helper.dart';
+
+void main() {
+ testOrder();
+ testDowncast();
+ testUpcast();
+ testNewSet();
+}
+
+void testOrder() {
+ var setEls = new Set<C>.from(elements); // Linked HashSet.
+ Expect.listEquals(elements, setEls.toList()); // Preserves order.
+}
+
+void testDowncast() {
+ var setEls = new Set<C>.from(elements);
+ var dSet = Set.castFrom<C, D>(setEls);
+
+ // Preserves order.
+ Expect.throws(() => dSet.first); // C is not D.
+ Expect.equals(d, dSet.elementAt(1));
+ Expect.throws(() => dSet.elementAt(2)); // E is not D.
+ Expect.equals(f, dSet.elementAt(3));
+ Expect.equals(null, dSet.elementAt(4));
+
+ Expect.throws(() => dSet.toList());
+
+ // Contains should not be typed.
+ var newC = new C();
+ Expect.isFalse(dSet.contains(newC));
+ Expect.throws(() => dSet.add(newC));
+ Expect.isFalse(dSet.contains(newC));
+ Expect.isTrue(dSet.contains(c));
+
+ // Remove and length should not be typed.
+ Expect.equals(5, dSet.length);
+ dSet.remove(c); // Success, no type checks.
+ Expect.equals(4, dSet.length);
+}
+
+void testUpcast() {
+ var setEls = new Set<C>.from(elements);
+ var objectSet = Set.castFrom<C, Object>(setEls);
+
+ Expect.listEquals(elements, objectSet.toList());
+
+ var newObject = new Object();
+ Expect.throws(() => objectSet.add(newObject));
+ Expect.isFalse(objectSet.contains(newObject));
+
+ var toSet = objectSet.toSet();
+ Expect.isTrue(toSet is LinkedHashSet<Object>);
+ Expect.isFalse(toSet is LinkedHashSet<C>);
+}
+
+void testNewSet() {
+ // Specified custom newSet as empty HashSet.
+ var setEls = new Set<C>.from(elements);
+ var customNewSet;
+ var objectSet2 = Set.castFrom<C, Object>(setEls,
+ newSet: <T>() => customNewSet = new HashSet<T>());
+
+ var customToSet = objectSet2.toSet();
+ Expect.isTrue(customToSet is HashSet<Object>);
+ Expect.isFalse(customToSet is HashSet<C>);
+ Expect.identical(customToSet, customNewSet);
+}
diff --git a/tests/corelib_2/cast_test.dart b/tests/corelib_2/cast_test.dart
deleted file mode 100644
index 36efe9e..0000000
--- a/tests/corelib_2/cast_test.dart
+++ /dev/null
@@ -1,186 +0,0 @@
-// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "dart:collection";
-import "dart:typed_data";
-import "package:expect/expect.dart";
-
-void main() {
- testIterable();
- testList();
-}
-
-final elements = <C>[c, d, e, f, null];
-
-void testIterable() {
- var iterable = new Iterable<C>.generate(elements.length, (n) => elements[n]);
- // Down-cast
- {
- // An iterable that (likely) can do direct access.
- var dIterable = Iterable.castFrom<C, D>(iterable);
-
- Expect.throws(() => dIterable.first, null, "1.first");
- Expect.equals(d, dIterable.elementAt(1));
- Expect.throws(() => dIterable.elementAt(2), null, "1.2"); // E is not D.
- Expect.equals(f, dIterable.skip(3).first); // Skip does not access element.
- Expect.equals(null, dIterable.skip(3).elementAt(1));
-
- Expect.throws(() => dIterable.toList(), null, "1.toList");
- }
-
- {
- // An iterable that cannot do direct access.
- var dIterable2 = Iterable.castFrom<C, D>(iterable.where((_) => true));
-
- Expect.throws(() => dIterable2.first, null, "2.first");
- Expect.equals(d, dIterable2.elementAt(1));
- Expect.throws(() => dIterable2.elementAt(2), null, "2.2"); // E is not D.
- Expect.equals(f, dIterable2.skip(3).first); // Skip does not access element.
- Expect.equals(null, dIterable2.skip(3).elementAt(1));
-
- Expect.throws(() => dIterable2.toList(), null, "2.toList");
- }
-
- {
- // Iterable that definitely won't survive accessing element 2.
- var iterable3 = new Iterable<C>.generate(
- elements.length, (n) => n == 3 ? throw "untouchable" : elements[n]);
- var dIterable3 = Iterable.castFrom<C, D>(iterable3);
-
- Expect.throws(() => dIterable3.first, null, "3.first");
- Expect.equals(d, dIterable3.elementAt(1));
- Expect.throws(() => dIterable3.elementAt(3), null, "3.3");
- // Skip does not access element.
- Expect.equals(null, dIterable3.skip(4).first);
- Expect.equals(null, dIterable3.skip(3).elementAt(1));
-
- Expect.throws(() => dIterable3.toList(), null, "3.toList");
- }
-
- // Up-cast.
- {
- var oIterable4 = Iterable.castFrom<C, Object>(iterable);
- Expect.listEquals(elements, oIterable4.toList());
- }
-}
-
-void testList() {
- // Down-cast.
- var list = new List<C>.from(elements);
- var dList = List.castFrom<C, D>(list);
-
- Expect.throws(() => dList.first); // C is not D.
- Expect.equals(d, dList[1]);
- Expect.throws(() => dList[2]); // E is not D.
- Expect.equals(f, dList[3]);
- Expect.equals(null, dList.last);
-
- Expect.throws(() => dList.toList());
-
- dList[2] = d;
- Expect.equals(d, dList[2]); // Setting works.
-
- // Up-cast.
- var list2 = new List<C>.from(elements);
- var dList2 = List.castFrom<C, Object>(list2);
- Expect.listEquals(elements, dList2);
- Expect.throws(() => dList2[2] = new Object()); // Cannot set non-C.
- Expect.listEquals(elements, dList2);
-
- // Regression test.
- var list3 = <num>[4, 3, 2, 1];
- var dList3 = list3.cast<int>();
- dList3.sort(null);
- Expect.listEquals([1, 2, 3, 4], list3);
-}
-
-void testSet() {
- var set = new Set<C>.from(elements); // Linked HashSet.
- Expect.listEquals(elements, set.toList()); // Preserves order.
-
- var dSet = Set.castFrom<C, D>(set);
-
- // Preserves order.
- Expect.throws(() => dSet.first); // C is not D.
- Expect.equals(d, dSet.elementAt(1));
- Expect.throws(() => dSet.elementAt(2)); // E is not D.
-
- Expect.throws(() => dSet.toList());
-
- // Contains is not typed.
- var newC = new C();
- Expect.isFalse(dSet.contains(newC));
- dSet.add(newC);
- Expect.isTrue(dSet.contains(newC));
-
- Expect.equals(5, dSet.length);
- dSet.remove(newC);
- Expect.equals(5, dSet.length);
- dSet.remove(c); // Success, no type checks.
- Expect.equals(4, dSet.length);
-
- // Up-cast
- var set2 = new Set<C>.from(elements);
- var dSet2 = Set.castFrom<C, Object>(set2);
-
- var newObject = new Object();
- Expect.throws(() => dSet2.add(newObject));
- Expect.isFalse(dSet.contains(newObject));
-
- var toSet2 = dSet2.toSet();
- Expect.isTrue(toSet2 is LinkedHashSet<Object>);
- Expect.isTrue(toSet2 is! LinkedHashSet<C>);
-
- // Custom emptySet.
-
- var set3 = new Set<C>.from(elements);
- var dSet3 = Set.castFrom<C, Object>(set3, newSet: <T>() => new HashSet<T>());
-
- var toSet3 = dSet3.toSet();
- Expect.isTrue(toSet3 is HashSet<Object>);
- Expect.isTrue(toSet3 is HashSet<C>);
- Expect.isTrue(toSet3 is! LinkedHashSet<Object>);
-}
-
-void testMap() {
- var map = new Map.fromIterables(elements, elements);
-
- var dMap = Map.castFrom<C, C, D, D>(map);
-
- Expect.isTrue(dMap is Map<D, D>);
-
- Expect.equals(null, dMap[new C()]);
- Expect.throws(() => dMap[c]);
- Expect.isTrue(dMap.containsKey(c));
- Expect.equals(d, dMap[d]);
- Expect.throws(() => dMap[e]);
- Expect.equals(null, dMap[null]);
-
- Expect.equals(5, dMap.length);
- dMap.remove(c); // Success, no type checks along the way.
- Expect.equals(4, dMap.length);
- Expect.equals(null, dMap[c]);
-
- Expect.throws(() => dMap[c] = d);
- Expect.throws(() => dMap[d] = c);
- Expect.equals(4, dMap.length);
-
- Expect.isTrue(dMap.keys is Iterable<D>);
- Expect.isTrue(dMap.values is Iterable<D>);
- Expect.throws(() => dMap.keys.toList());
- Expect.throws(() => dMap.values.toList());
-}
-
-class C {}
-
-class D extends C {}
-
-class E extends C {}
-
-class F implements D, E {}
-
-final c = new C();
-final d = new D();
-final e = new E();
-final f = new F();
diff --git a/tests/language/extension_methods/basic_static_extension_test.dart b/tests/language/extension_methods/basic_static_extension_test.dart
new file mode 100644
index 0000000..7256a98
--- /dev/null
+++ b/tests/language/extension_methods/basic_static_extension_test.dart
@@ -0,0 +1,124 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+import "package:expect/expect.dart";
+
+// Tests the syntax of extension methods, and that the extensions are
+// invocable, and that type variables are bound correctly.
+
+// There are no extension *conflicts*.
+// For each invocation, there is exactly one extension member in scope
+// which applies.
+
+// Target types.
+class Unnamed {}
+
+class Named {}
+
+class UnnamedGeneric<T> {}
+
+class NamedGeneric<T> {}
+
+String str(String name, Object? object) =>
+ "$name(${object == null ? "null" : "non-null"})";
+
+// Unnamed local extension.
+extension on Unnamed? {
+ String get name => str("unnamed", this);
+}
+
+extension NamedExt on Named? {
+ String get name => str("named", this);
+}
+
+extension<T> on UnnamedGeneric<T>? {
+ String get name => str("unnamed generic", this);
+ List<T> get list => <T>[];
+}
+
+extension NamedGenericExt<T> on NamedGeneric<T>? {
+ String get name => str("named generic", this);
+ List<T> get list => <T>[];
+}
+
+extension General on Object? {
+ String get generalName => str("general", this);
+}
+
+extension GeneralGeneric<T> on T {
+ String get generalGenericName => str("general generic", this);
+ List<T> get generalList => <T>[];
+}
+
+main() {
+ // Unnamed.
+ Unnamed unnamed = Unnamed();
+ Unnamed? unnamedNull = null;
+
+ Expect.equals("unnamed(non-null)", unnamed.name);
+ Expect.equals("unnamed(null)", unnamedNull.name);
+
+ Expect.equals("general(non-null)", unnamed.generalName);
+ Expect.equals("general(null)", unnamedNull.generalName);
+
+ Expect.equals("general generic(non-null)", unnamed.generalGenericName);
+ Expect.equals("general generic(null)", unnamedNull.generalGenericName);
+ Expect.type<List<Unnamed>>(unnamed.generalList);
+ Expect.type<List<Unnamed?>>(unnamedNull.generalList);
+
+ // Named.
+ Named named = Named();
+ Named? namedNull = null;
+
+ Expect.equals("named(non-null)", named.name);
+ Expect.equals("named(null)", namedNull.name);
+
+ Expect.equals("general(non-null)", named.generalName);
+ Expect.equals("general(null)", namedNull.generalName);
+
+ Expect.equals("general generic(non-null)", named.generalGenericName);
+ Expect.equals("general generic(null)", namedNull.generalGenericName);
+ Expect.type<List<Named>>(named.generalList);
+ Expect.type<List<Named?>>(namedNull.generalList);
+
+ // Unnamed Generic.
+ UnnamedGeneric<num> unnamedGeneric = UnnamedGeneric<int>();
+ UnnamedGeneric<num>? unnamedGenericNull = null;
+
+ Expect.equals("unnamed generic(non-null)", unnamedGeneric.name);
+ Expect.equals("unnamed generic(null)", unnamedGenericNull.name);
+ Expect.type<List<num>>(unnamedGeneric.list);
+ Expect.notType<List<int>>(unnamedGeneric.list);
+ Expect.type<List<num>>(unnamedGenericNull.list);
+ Expect.notType<List<int>>(unnamedGenericNull.list);
+
+ Expect.equals("general(non-null)", unnamedGeneric.generalName);
+ Expect.equals("general(null)", unnamedGenericNull.generalName);
+
+ Expect.equals("general generic(non-null)", unnamedGeneric.generalGenericName);
+ Expect.equals("general generic(null)", unnamedGenericNull.generalGenericName);
+ Expect.type<List<UnnamedGeneric<num>>>(unnamedGeneric.generalList);
+ Expect.type<List<UnnamedGeneric<num>?>>(unnamedGenericNull.generalList);
+
+ // Named Generic.
+ NamedGeneric<num> namedGeneric = NamedGeneric<int>();
+ NamedGeneric<num>? namedGenericNull = null;
+
+ Expect.equals("named generic(non-null)", namedGeneric.name);
+ Expect.equals("named generic(null)", namedGenericNull.name);
+ Expect.type<List<num>>(namedGeneric.list);
+ Expect.notType<List<int>>(namedGeneric.list);
+ Expect.type<List<num>>(namedGenericNull.list);
+ Expect.notType<List<int>>(namedGenericNull.list);
+
+ Expect.equals("general(non-null)", namedGeneric.generalName);
+ Expect.equals("general(null)", namedGenericNull.generalName);
+
+ Expect.equals("general generic(non-null)", namedGeneric.generalGenericName);
+ Expect.equals("general generic(null)", namedGenericNull.generalGenericName);
+ Expect.type<List<NamedGeneric<num>>>(namedGeneric.generalList);
+ Expect.type<List<NamedGeneric<num>?>>(namedGenericNull.generalList);
+}
diff --git a/tests/language/extension_methods/extension_operation_in_const_test.dart b/tests/language/extension_methods/extension_operation_in_const_test.dart
new file mode 100644
index 0000000..4dc4b6a
--- /dev/null
+++ b/tests/language/extension_methods/extension_operation_in_const_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+extension on Object {
+ int operator -() => 42;
+ int get length => 5;
+}
+
+class Tester {
+ final value;
+ const Tester.neg(Object o) : value = -o;
+ const Tester.length(Object o) : value = o.length;
+}
+
+main() {
+ const //
+ Object //# neg: compile-time error
+ i = 2;
+ const int x = -i;
+ print(x);
+
+ const //
+ Object //# length: compile-time error
+ s = "fisk";
+ const int y = s.length;
+ print(y);
+
+ Expect.equals(42, new Tester.neg(3).value);
+ const tx = Tester.neg(42); //# tneg: compile-time error
+ print(tx); //# tneg: continued
+
+ Expect.equals(5, new Tester.length("abc").value);
+ const ty = Tester.length("abc"); //# tlength: compile-time error
+ print(ty); //# tlength: continued
+}
diff --git a/tests/language/extension_methods/helpers/also_on_object.dart b/tests/language/extension_methods/helpers/also_on_object.dart
new file mode 100644
index 0000000..afe30e34
--- /dev/null
+++ b/tests/language/extension_methods/helpers/also_on_object.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// An extension conflicting with the one from "on_object.dart";
+extension AlsoOnObject on Object {
+ String get onObject => "also object";
+}
diff --git a/tests/language/extension_methods/helpers/class_no_shadow.dart b/tests/language/extension_methods/helpers/class_no_shadow.dart
new file mode 100644
index 0000000..31e8195
--- /dev/null
+++ b/tests/language/extension_methods/helpers/class_no_shadow.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+const String instanceValue = "1";
+
+void checkInstanceValue(String other) {
+ Expect.equals(other, instanceValue);
+}
+
+// A class which has only its own instance methods
+class A {
+ String fieldInInstanceScope = instanceValue;
+ String get getterInInstanceScope => instanceValue;
+ set setterInInstanceScope(String x) {
+ checkInstanceValue(x);
+ }
+
+ String methodInInstanceScope() => instanceValue;
+}
diff --git a/tests/language/extension_methods/helpers/class_shadow.dart b/tests/language/extension_methods/helpers/class_shadow.dart
new file mode 100644
index 0000000..2e603d1a
--- /dev/null
+++ b/tests/language/extension_methods/helpers/class_shadow.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+import "class_no_shadow.dart";
+
+// A class which has its own instance methods, which also
+// shadows the global scope
+class AGlobal extends A {
+ String fieldInGlobalScope = instanceValue;
+ String get getterInGlobalScope => instanceValue;
+ set setterInGlobalScope(String x) {
+ checkInstanceValue(x);
+ }
+
+ String methodInGlobalScope() => instanceValue;
+}
diff --git a/tests/language/extension_methods/helpers/extension_all.dart b/tests/language/extension_methods/helpers/extension_all.dart
new file mode 100644
index 0000000..80656a7
--- /dev/null
+++ b/tests/language/extension_methods/helpers/extension_all.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+import "class_no_shadow.dart";
+
+const double otherExtensionValue = 1.234;
+
+void checkOtherExtensionValue(double other) {
+ Expect.equals(other, otherExtensionValue);
+}
+
+// An extension which defines all symbols
+extension ExtraExt on A {
+ double get fieldInGlobalScope => otherExtensionValue;
+ double get getterInGlobalScope => otherExtensionValue;
+ set setterInGlobalScope(double x) {
+ checkOtherExtensionValue(x);
+ }
+
+ double methodInGlobalScope() => otherExtensionValue;
+
+ double get fieldInInstanceScope => otherExtensionValue;
+ double get getterInInstanceScope => otherExtensionValue;
+ set setterInInstanceScope(double x) {
+ checkOtherExtensionValue(x);
+ }
+
+ double methodInInstanceScope() => otherExtensionValue;
+
+ double get fieldInExtensionScope => otherExtensionValue;
+ double get getterInExtensionScope => otherExtensionValue;
+ set setterInExtensionScope(double x) {
+ checkOtherExtensionValue(x);
+ }
+
+ double methodInExtensionScope() => otherExtensionValue;
+
+ double get fieldInOtherExtensionScope => otherExtensionValue;
+ double get getterInOtherExtensionScope => otherExtensionValue;
+ set setterInOtherExtensionScope(double x) {
+ checkOtherExtensionValue(x);
+ }
+
+ double methodInOtherExtensionScope() => otherExtensionValue;
+}
diff --git a/tests/language/extension_methods/helpers/extension_global_instance.dart b/tests/language/extension_methods/helpers/extension_global_instance.dart
new file mode 100644
index 0000000..1fbbe7b
--- /dev/null
+++ b/tests/language/extension_methods/helpers/extension_global_instance.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+import "class_no_shadow.dart";
+
+const double otherExtensionValue = 1.234;
+
+void checkOtherExtensionValue(double other) {
+ Expect.equals(other, otherExtensionValue);
+}
+
+// An extension which defines only global, instance and its own symbols
+extension ExtraExt on A {
+ double get fieldInGlobalScope => otherExtensionValue;
+ double get getterInGlobalScope => otherExtensionValue;
+ set setterInGlobalScope(double x) {
+ checkOtherExtensionValue(x);
+ }
+
+ double methodInGlobalScope() => otherExtensionValue;
+
+ double get fieldInInstanceScope => otherExtensionValue;
+ double get getterInInstanceScope => otherExtensionValue;
+ set setterInInstanceScope(double x) {
+ checkOtherExtensionValue(x);
+ }
+
+ double methodInInstanceScope() => otherExtensionValue;
+
+ double get fieldInOtherExtensionScope => otherExtensionValue;
+ double get getterInOtherExtensionScope => otherExtensionValue;
+ set setterInOtherExtensionScope(double x) {
+ checkOtherExtensionValue(x);
+ }
+
+ double methodInOtherExtensionScope() => otherExtensionValue;
+}
diff --git a/tests/language/extension_methods/helpers/extension_only.dart b/tests/language/extension_methods/helpers/extension_only.dart
new file mode 100644
index 0000000..d625af7
--- /dev/null
+++ b/tests/language/extension_methods/helpers/extension_only.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+import "class_no_shadow.dart";
+
+const double otherExtensionValue = 1.234;
+
+void checkOtherExtensionValue(double other) {
+ Expect.equals(other, otherExtensionValue);
+}
+
+// An extension which defines only its own symbols
+extension ExtraExt on A {
+ double get fieldInOtherExtensionScope => otherExtensionValue;
+ double get getterInOtherExtensionScope => otherExtensionValue;
+ set setterInOtherExtensionScope(double x) {
+ checkOtherExtensionValue(x);
+ }
+
+ double methodInOtherExtensionScope() => otherExtensionValue;
+}
diff --git a/tests/language/extension_methods/helpers/global_scope.dart b/tests/language/extension_methods/helpers/global_scope.dart
new file mode 100644
index 0000000..ae6f4fe
--- /dev/null
+++ b/tests/language/extension_methods/helpers/global_scope.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+const int globalValue = 0;
+
+void checkGlobalValue(int x) {
+ Expect.equals(x, globalValue);
+}
+
+// Add symbols to the global scope
+int fieldInGlobalScope = globalValue;
+int get getterInGlobalScope => globalValue;
+set setterInGlobalScope(int x) {
+ checkGlobalValue(x);
+}
+
+int methodInGlobalScope() => globalValue;
diff --git a/tests/language/extension_methods/helpers/on_int.dart b/tests/language/extension_methods/helpers/on_int.dart
new file mode 100644
index 0000000..a835f16
--- /dev/null
+++ b/tests/language/extension_methods/helpers/on_int.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+extension OnInt on int {
+ String get onObject => "int";
+ String get onInt => "int";
+}
diff --git a/tests/language/extension_methods/helpers/on_object.dart b/tests/language/extension_methods/helpers/on_object.dart
new file mode 100644
index 0000000..dfca4d6
--- /dev/null
+++ b/tests/language/extension_methods/helpers/on_object.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+extension OnObject on Object {
+ String get onObject => "object";
+}
diff --git a/tests/language/extension_methods/static_extension_bounds_error_test.dart b/tests/language/extension_methods/static_extension_bounds_error_test.dart
new file mode 100644
index 0000000..d78b2a8
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_bounds_error_test.dart
@@ -0,0 +1,137 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+// Tests bounds checking for extension methods
+
+extension E1<T extends num> on T {
+ int get e1 => 1;
+}
+
+extension E2<T extends S, S extends num> on T {
+ int get e2 => 2;
+}
+
+extension E3<T> on T {
+ S f3<S extends T>(S x) => x;
+}
+
+extension E4<T extends Rec<T>> on T {
+ int get e4 => 4;
+}
+
+class Rec<T extends Rec<T>> {}
+
+class RecSolution extends Rec<RecSolution> {}
+
+void main() {
+ String s = "s";
+ int i = 0;
+ double d = 1.0;
+
+ // Inferred type of String does not satisfy the bound.
+ s.e1;
+// ^^
+// [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
+// [cfe] The getter 'e1' isn't defined for the class 'String'.
+ E1(s).e1;
+//^^
+// [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
+// [cfe] Inferred type argument 'String' doesn't conform to the bound 'num' of the type variable 'T' on 'E1|get#e1'.
+ E1<String>(s).e1;
+//^
+// [cfe] Type argument 'String' doesn't conform to the bound 'num' of the type variable 'T' on 'E1|get#e1'.
+// ^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
+
+ // Inferred types of int and double are ok
+ i.e1;
+ E1(i).e1;
+ E1<int>(i).e1;
+ d.e1;
+ E1(d).e1;
+ E1<double>(d).e1;
+
+ // Inferred type of String does not satisfy the bound.
+ s.e2;
+// ^^
+// [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
+// [cfe] The getter 'e2' isn't defined for the class 'String'.
+ E2(s).e2;
+//^^
+// [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
+// [cfe] Inferred type argument 'String' doesn't conform to the bound 'S' of the type variable 'T' on 'E2|get#e2'.
+ E2<String, num>(s).e2;
+//^
+// [cfe] Type argument 'String' doesn't conform to the bound 'S' of the type variable 'T' on 'E2|get#e2'.
+// ^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
+
+ // Inferred types of int and double are ok
+ i.e2;
+ E2(i).e2;
+ E2<int, num>(i).e2;
+ d.e2;
+ E2(d).e2;
+ E2<double, num>(d).e2;
+
+ // Inferred type int for method type parameter doesn't match the inferred
+ // bound of String
+ s.f3(3);
+// ^^
+// [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
+// [cfe] Inferred type argument 'int' doesn't conform to the bound 'T' of the type variable 'S' on 'E3|f3'.
+ E3(s).f3(3);
+// ^^
+// [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
+// [cfe] Inferred type argument 'int' doesn't conform to the bound 'T' of the type variable 'S' on 'E3|f3'.
+ E3<String>(s).f3(3);
+// ^^
+// [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
+// [cfe] Inferred type argument 'int' doesn't conform to the bound 'T' of the type variable 'S' on 'E3|f3'.
+
+ // Inferred type int for method type parameter is ok
+ i.f3(3);
+ E3(i).f3(3);
+ E3<int>(i).f3(3);
+
+ // Inferred type int for method type parameter doesn't match the inferred
+ // bound of double
+ d.f3(3);
+// ^^
+// [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
+// [cfe] Inferred type argument 'int' doesn't conform to the bound 'T' of the type variable 'S' on 'E3|f3'.
+ E3(d).f3(3);
+// ^^
+// [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
+// [cfe] Inferred type argument 'int' doesn't conform to the bound 'T' of the type variable 'S' on 'E3|f3'.
+ E3<double>(d).f3(3);
+// ^^
+// [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
+// [cfe] Inferred type argument 'int' doesn't conform to the bound 'T' of the type variable 'S' on 'E3|f3'.
+
+ RecSolution recs = RecSolution();
+ Rec<dynamic> superRec = RecSolution(); // Super-bounded type.
+
+ // Inferred type of RecSolution is ok
+ recs.e4;
+ E4(recs).e4;
+ E4<RecSolution>(recs).e4;
+
+ // Inferred super-bounded type is invalid as type argument
+ superRec.e4;
+// ^^
+// [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
+// [cfe] The getter 'e4' isn't defined for the class 'Rec<dynamic>'.
+ E4(superRec).e4;
+//^^
+// [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
+// [cfe] Inferred type argument 'Rec<dynamic>' doesn't conform to the bound 'Rec<T>' of the type variable 'T' on 'E4|get#e4'.
+ E4<Rec<dynamic>>(superRec).e4;
+//^
+// [cfe] Type argument 'Rec<dynamic>' doesn't conform to the bound 'Rec<T>' of the type variable 'T' on 'E4|get#e4'.
+// ^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
+}
diff --git a/tests/language/extension_methods/static_extension_constant_error_test.dart b/tests/language/extension_methods/static_extension_constant_error_test.dart
new file mode 100644
index 0000000..e7a0d0c
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_constant_error_test.dart
@@ -0,0 +1,90 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+import 'static_extension_constant_lib.dart';
+
+// Tests that it is an error to invoke an extension method during constant
+// expression evaluation. The expressions should be the same as those in
+// `runtimeExtensionCalls`, so that it is verified that each of them will
+// invoke an extension method.
+
+void main() {
+ // The initializing expressions should be identical to the elements in
+ // `runtimeExtensionCalls`.
+
+ const c01 = ~i;
+ // ^^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+ const c02 = b & b;
+ // ^^^^^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+ const c03 = b | b;
+ // ^^^^^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+ const c04 = b ^ b;
+ // ^^^^^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+ const c05 = i ~/ i;
+ // ^^^^^^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+ const c06 = i >> i;
+ // ^^^^^^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+ const c08 = i << i;
+ // ^^^^^^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+ const c09 = i + i;
+ // ^^^^^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+ const c10 = -i;
+ // ^^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+ const c11 = d - d;
+ // ^^^^^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+ const c12 = d * d;
+ // ^^^^^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+ const c13 = d / d;
+ // ^^^^^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+ const c14 = d % d;
+ // ^^^^^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+ const c15 = d < i;
+ // ^^^^^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+ const c16 = i <= d;
+ // ^^^^^^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+ const c17 = d > i;
+ // ^^^^^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+ const c18 = i >= i;
+ // ^^^^^^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+ const c19 = s.length;
+ // ^^^^^^^^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+}
diff --git a/tests/language/extension_methods/static_extension_constant_lib.dart b/tests/language/extension_methods/static_extension_constant_lib.dart
new file mode 100644
index 0000000..23d6de9
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_constant_lib.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+extension ExtendObject on Object {
+ int operator ~() => 1;
+ bool operator &(Object other) => false;
+ bool operator |(Object other) => false;
+ bool operator ^(Object other) => true;
+ int operator ~/(Object other) => 0;
+ int operator >>(Object other) => 1;
+ // int operator >>>(Object other) => 2; // Requires triple-shift.
+ int operator <<(Object other) => 0;
+ int operator +(Object other) => 0;
+ double operator -() => 1.0;
+ double operator -(Object other) => 1.0;
+ double operator *(Object other) => 1.0;
+ double operator /(Object other) => 2.0;
+ double operator %(Object other) => 1.0;
+ bool operator <(Object other) => false;
+ bool operator <=(Object other) => true;
+ bool operator >(Object other) => true;
+ bool operator >=(Object other) => false;
+ int get length => 1;
+}
+
+const Object b = true;
+const Object i = 3;
+const Object d = 2.4;
+const Object s = 'Hello!';
+
+// These expressions should be identical to the ones in
+// static_extension_constant_{,error}_test.dart, to ensure that
+// they invoke an extension method, and that this is an error.
+var runtimeExtensionCalls = <Object>[
+ ~i,
+ b & b,
+ b | b,
+ b ^ b,
+ i ~/ i,
+ i >> i,
+ // i >>> i, // Requries triple-shift.
+ i << i,
+ i + i,
+ -i,
+ d - d,
+ d * d,
+ d / d,
+ d % d,
+ d < i,
+ i <= d,
+ d > i,
+ i >= i,
+ s.length,
+];
diff --git a/tests/language/extension_methods/static_extension_constant_test.dart b/tests/language/extension_methods/static_extension_constant_test.dart
new file mode 100644
index 0000000..1295d4a
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_constant_test.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+import 'package:expect/expect.dart';
+import 'static_extension_constant_lib.dart' hide b, i, d, s;
+import 'static_extension_constant_lib.dart' as lib show b, i, d, s;
+
+// Ensure that all expressions in runtimeExtensionCalls invoke
+// an extension method rather than an instance method, such that
+// static_extension_constant_error_test gets an error for them all.
+
+const dynamic b = lib.b;
+const dynamic i = lib.i;
+const dynamic d = lib.d;
+const dynamic s = lib.s;
+
+// These expressions should be identical to those in
+// `lib.runtimeExtensionCalls`.
+var dynamicInstanceCalls = <Object>[
+ ~i,
+ b & b,
+ b | b,
+ b ^ b,
+ i ~/ i,
+ i >> i,
+ // i >>> i, // Requries triple-shift.
+ i << i,
+ i + i,
+ -i,
+ d - d,
+ d * d,
+ d / d,
+ d % d,
+ d < i,
+ i <= d,
+ d > i,
+ i >= i,
+ s.length,
+];
+
+void main() {
+ for (int i = 0; i < dynamicInstanceCalls.length; ++i) {
+ Expect.notEquals(dynamicInstanceCalls[i], runtimeExtensionCalls[i]);
+ }
+}
diff --git a/tests/language/extension_methods/static_extension_deferred_double_import_test.dart b/tests/language/extension_methods/static_extension_deferred_double_import_test.dart
new file mode 100644
index 0000000..0ef1f33
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_deferred_double_import_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+import "helpers/on_object.dart";
+import "helpers/on_object.dart" deferred as p1 hide OnObject;
+
+// Allow explicit and implicit access to non-deferred import extensions.
+
+void main() async {
+ Object o = 1;
+ Expect.equals("object", OnObject(o).onObject);
+ Expect.equals("object", o.onObject);
+}
diff --git a/tests/language/extension_methods/static_extension_deferred_import_error_test.dart b/tests/language/extension_methods/static_extension_deferred_import_error_test.dart
new file mode 100644
index 0000000..3d0c5ba
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_deferred_import_error_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// It is an error to import a deferred library containing extensions without
+// hiding them.
+import "helpers/on_object.dart" deferred as p1;
+// [error line 9, column 1]
+// [cfe] Extension 'OnObject' cannot be imported through a deferred import.
+// ^^^^^^^^^^^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.DEFERRED_IMPORT_OF_EXTENSION
+
+void main() async {}
diff --git a/tests/language/extension_methods/static_extension_deferred_import_resolution_error_test.dart b/tests/language/extension_methods/static_extension_deferred_import_resolution_error_test.dart
new file mode 100644
index 0000000..59920e7
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_deferred_import_resolution_error_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+import "helpers/on_object.dart" deferred as p1 hide OnObject;
+
+void main() {
+ Object o = 1;
+ OnObject(o).onObject;
+//^^^^^^^^
+// [analyzer] STATIC_TYPE_WARNING.UNDEFINED_FUNCTION
+// [cfe] Method not found: 'OnObject'.
+ o.onObject;
+ //^^^^^^^^
+ // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
+ // [cfe] The getter 'onObject' isn't defined for the class 'Object'.
+}
diff --git a/tests/language/extension_methods/static_extension_deferred_import_test.dart b/tests/language/extension_methods/static_extension_deferred_import_test.dart
new file mode 100644
index 0000000..829a242
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_deferred_import_test.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+import "helpers/on_object.dart" deferred as p1 hide OnObject;
+
+void main() {}
diff --git a/tests/language/extension_methods/static_extension_getter_setter_conflicts_test.dart b/tests/language/extension_methods/static_extension_getter_setter_conflicts_test.dart
new file mode 100644
index 0000000..686c40f
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_getter_setter_conflicts_test.dart
@@ -0,0 +1,253 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+// Tests interactions between getters and setters where there is a conflict.
+
+// Conflicting class declarations.
+
+class C0 {
+ int get m1 => 0;
+ void set m2(int x) {}
+ int operator [](int index) => 0;
+}
+
+extension E0 on C0 {
+ void set m1(int x) {}
+ int get m2 => 0;
+ void operator []=(int index, int value) {}
+}
+
+void test0() {
+ C0 c0 = C0();
+ c0.m1;
+ c0.m1 = 0;
+ // ^^
+ // [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+ // [cfe] The setter 'm1' isn't defined for the class 'C0'.
+ E0(c0).m1 = 0;
+ E0(c0).m1;
+ // ^^
+ // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_EXTENSION_GETTER
+ // [cfe] Getter not found: 'm1'.
+
+ c0.m1 += 0;
+ // ^^
+ // [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+ // [cfe] The setter 'm1' isn't defined for the class 'C0'.
+
+ c0.m1++;
+ // ^^
+ // [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+ // [cfe] The setter 'm1' isn't defined for the class 'C0'.
+
+ c0.m2 = 0;
+ c0.m2;
+ // ^^
+ // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
+ // [cfe] The getter 'm2' isn't defined for the class 'C0'.
+ c0.m2 += 0;
+ // ^^
+ // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
+ // [cfe] The getter 'm2' isn't defined for the class 'C0'.
+ c0.m2++;
+ // ^^
+ // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
+ // [cfe] The getter 'm2' isn't defined for the class 'C0'.
+
+ E0(c0).m2;
+
+ c0[0];
+ c0[0] = 0;
+ //^^^
+ // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_OPERATOR
+ // [cfe] The operator '[]=' isn't defined for the class 'C0'.
+ E0(c0)[0];
+ // ^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_EXTENSION_OPERATOR
+ // [cfe] Getter not found: '[]'.
+ E0(c0)[0] = 0;
+
+ c0[0] += 0;
+ //^^^
+ // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_OPERATOR
+ // [cfe] The operator '[]=' isn't defined for the class 'C0'.
+ c0[0]++;
+ //^^^
+ // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_OPERATOR
+ // [cfe] The operator '[]=' isn't defined for the class 'C0'.
+
+ E0(c0)[0] += 0;
+ // ^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_EXTENSION_OPERATOR
+ // [cfe] The operator '[]' isn't defined for the class 'C0'.
+ E0(c0)[0]++;
+ // ^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_EXTENSION_OPERATOR
+ // [cfe] The operator '[]' isn't defined for the class 'C0'.
+}
+
+// Conflicting extensions.
+
+class C1<T> {}
+
+extension E1A<T> on C1<T> {
+ int get m1 => 0;
+ void set m2(int x) {}
+ int operator [](int index) => 0;
+}
+
+extension E1B on C1<Object?> {
+ void set m1(int x) {}
+ int get m2 => 0;
+ void operator []=(int index, int value) {}
+}
+
+void test1() {
+ C1<int> c1a = C1(); // E1A is more specific.
+ c1a.m1;
+
+ c1a.m1 = 0;
+ // ^^
+ // [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_LOCAL
+ // [cfe] The setter 'm1' isn't defined for the class 'C1<int>'.
+
+ c1a.m2;
+ // ^^
+ // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
+ // [cfe] The getter 'm2' isn't defined for the class 'C1<int>'.
+
+ c1a.m2 = 0;
+
+ c1a[0] = 0;
+ // ^^^
+ // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_OPERATOR
+ // [cfe] The operator '[]=' isn't defined for the class 'C1<int>'.
+
+ c1a[0] += 0;
+ // ^^^
+ // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_OPERATOR
+ // [cfe] The operator '[]=' isn't defined for the class 'C1<int>'.
+
+ c1a[0]++;
+ // ^^^
+ // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_OPERATOR
+ // [cfe] The operator '[]=' isn't defined for the class 'C1<int>'.
+
+ c1a[0];
+
+ C1<Object> c1b = C1<Object>(); // Neither extension is more specific.
+
+ c1b.m1;
+ // ^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The property 'm1' is defined in multiple extensions for 'C1<Object>' and neither is more specific.
+
+ c1b.m1 = 0;
+ // ^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The property 'm1' is defined in multiple extensions for 'C1<Object>' and neither is more specific.
+
+ c1b.m1 += 0;
+ // ^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The property 'm1' is defined in multiple extensions for 'C1<Object>' and neither is more specific.
+
+ c1b.m1++;
+ // ^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The property 'm1' is defined in multiple extensions for 'C1<Object>' and neither is more specific.
+
+ c1b.m2;
+ // ^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The property 'm2' is defined in multiple extensions for 'C1<Object>' and neither is more specific.
+
+ c1b[0];
+//^^^
+// [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+// ^
+// [cfe] The operator '[]' is defined in multiple extensions for 'C1<Object>' and neither is more specific.
+
+ c1b[0] = 0;
+//^^^
+// [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+// ^
+// [cfe] The operator '[]=' is defined in multiple extensions for 'C1<Object>' and neither is more specific.
+
+ c1b[0] += 0;
+//^^^
+// [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+// ^
+// [cfe] The operator '[]' is defined in multiple extensions for 'C1<Object>' and neither is more specific.
+// ^
+// [cfe] The operator '[]=' is defined in multiple extensions for 'C1<Object>' and neither is more specific.
+
+ c1b[0]++;
+//^^^
+// [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+// ^
+// [cfe] The operator '[]' is defined in multiple extensions for 'C1<Object>' and neither is more specific.
+// ^
+// [cfe] The operator '[]=' is defined in multiple extensions for 'C1<Object>' and neither is more specific.
+}
+
+// Getter on the extension itself.
+class C2 {
+ int get m1 => 0;
+ void set m2(int x) {}
+ int get mc => 0;
+ void operator []=(int index, int value) {}
+}
+
+extension E2 on C2 {
+ void set m1(int x) {}
+ int get m2 => 0;
+ String get me => "";
+ int operator [](int index) => 0;
+
+ void test2() {
+ // Using `this.member` means using the `on` type.
+
+ this.m1;
+ this.m1 = 0;
+ // ^^
+ // [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+ // [cfe] The setter 'm1' isn't defined for the class 'C2'.
+
+ this.m2 = 0;
+ this.m2;
+ // ^^
+ // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
+ // [cfe] The getter 'm2' isn't defined for the class 'C2'.
+
+ this[0] = 0;
+ this[0];
+ // ^^^
+ // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_OPERATOR
+ // [cfe] The operator '[]' isn't defined for the class 'C2'.
+
+ this[0] += 0;
+ // ^^^
+ // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_OPERATOR
+ // [cfe] The operator '[]' isn't defined for the class 'C2'.
+
+ this[0]++;
+ // ^^^
+ // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_OPERATOR
+ // [cfe] The operator '[]' isn't defined for the class 'C2'.
+
+ // Check that `this.mc` refers to `C2.mc`.
+ this.mc.toRadixString(16);
+ // Check that `this.me` refers to `E2.me`.
+ this.me.substring(0);
+ }
+}
+
+main() {
+ test0();
+ test1();
+ C2().test2();
+}
diff --git a/tests/language/extension_methods/static_extension_getter_setter_test.dart b/tests/language/extension_methods/static_extension_getter_setter_test.dart
new file mode 100644
index 0000000..7224cb5
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_getter_setter_test.dart
@@ -0,0 +1,145 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+// Tests getters and setters where one or both is defined
+// by an extension.
+
+import "package:expect/expect.dart";
+
+main() {
+ C c = C();
+ // v1: C get, C set
+ expectGet("C.v1", c.v1);
+ expectSet("C.v1=1", c.v1 = Result("1"));
+ // v2: C get, E1 get/set, C wins.
+ expectGet("C.v2", c.v2);
+ expectSet("E1.v2=2", E1(c).v2 = Result("2"));
+ // v3: E1 get/set, C set, C wins.
+ expectGet("E1.v3", E1(c).v3);
+ expectSet("C.v3=3", c.v3 = Result("3"));
+ // v4: E1 get/set
+ expectGet("E1.v4", c.v4);
+ expectSet("E1.v4=4", c.v4 = Result("4"));
+ // v5: E1 get, E2 set, neither more specific.
+ expectGet("E1.v5", E1(c).v5);
+ expectSet("E2.v5=5", E2(c).v5 = Result("5"));
+
+ expectSet("C.v1=C.v1+1", c.v1++);
+ expectSet("E1.v4=E1.v4+1", c.v4++);
+
+ expectSet("C.v1=C.v1+a", c.v1 += "a");
+ expectSet("C.v1=C.v1-b", c.v1 -= "b");
+ expectSet("E1.v4=E1.v4-b", c.v4 -= "b");
+
+ // Explicit application used by all accesses of read/write operations
+ expectSet("E1.v1=E1.v1+1", E1(c).v1++);
+ expectSet("E1.v2=E1.v2+1", E1(c).v2++);
+ expectSet("E1.v3=E1.v3+1", E1(c).v3++);
+ // Same using `+= 1` instead of `++`.
+ expectSet("E1.v1=E1.v1+1", E1(c).v1 += 1);
+ expectSet("E1.v2=E1.v2+1", E1(c).v2 += 1);
+ expectSet("E1.v3=E1.v3+1", E1(c).v3 += 1);
+ // Same fully expanded.
+ expectSet("E1.v1=E1.v1+1", E1(c).v1 = E1(c).v1 + 1);
+ expectSet("E1.v2=E1.v2+1", E1(c).v2 = E1(c).v2 + 1);
+ expectSet("E1.v3=E1.v3+1", E1(c).v3 = E1(c).v3 + 1);
+
+ // Cascades work.
+ expectSet(
+ "E1.v4=E1.v4+[C.v1=C.v1-[C.v3=a]]",
+ c
+ ..v3 = Result("a")
+ ..v1 -= Result("[$lastSetter]")
+ ..v4 += Result("[$lastSetter]"));
+}
+
+/// Expect the value of [result] to be the [expected] string
+expectGet(String expected, Result result) {
+ Expect.equals(expected, result.value);
+}
+
+/// Expect the [lastSetter] value set by evaluating [assignment] to be
+/// [expected].
+expectSet(String expected, void assignment) {
+ Expect.equals(expected, lastSetter);
+}
+
+/// Last value passed to any of our tested setters.
+String? lastSetter = null;
+
+/// A type which supports a `+` operation accepting `int`,
+/// so we can test `+=` and `++`.
+class Result {
+ final String value;
+ Result(this.value);
+ Result operator +(Object o) => Result("$value+$o");
+ Result operator -(Object o) => Result("$value-$o");
+ String toString() => value;
+}
+
+/// Target type for extensions.
+///
+/// Declares [v1] getter and setter, [v2] getter and [v3] setter.
+class C {
+ Result get v1 => Result("C.v1");
+ void set v1(Result value) {
+ lastSetter = "C.v1=$value";
+ }
+
+ Result get v2 => Result("C.v2");
+
+ void set v3(Result value) {
+ lastSetter = "C.v3=$value";
+ }
+}
+
+/// Primary extension on [C].
+///
+/// Declares [v1], [v2] and [v3] getters and setters.
+///
+/// Declares [v4] getter and setter, and [v5] getter
+/// which are supplemented by a setter from the [E2] extension.
+extension E1 on C {
+ // Same basename as C getter and setter.
+ Result get v1 => Result("E1.v1");
+
+ void set v1(Result value) {
+ lastSetter = "E1.v1=$value";
+ }
+
+ // Same basename as C getter.
+ Result get v2 => Result("E1.v2");
+
+ void set v2(Result value) {
+ lastSetter = "E1.v2=$value";
+ }
+
+ // Same basename as C setter.
+ Result get v3 => Result("E1.v3");
+
+ void set v3(Result value) {
+ lastSetter = "E1.v3=$value";
+ }
+
+ // No other declarations with same basename.
+ Result get v4 => Result("E1.v4");
+
+ void set v4(Result value) {
+ lastSetter = "E1.v4=$value";
+ }
+
+ // Same basename as E2 setter.
+ Result get v5 => Result("E1.v5");
+}
+
+/// A different extension than [E1] on [C].
+///
+/// Declares [v5] setter.
+extension E2 on C {
+ void set v5(Result value) {
+ lastSetter = "E2.v5=$value";
+ }
+}
diff --git a/tests/language/extension_methods/static_extension_import_hide_error_test.dart b/tests/language/extension_methods/static_extension_import_hide_error_test.dart
new file mode 100644
index 0000000..9a93aa0
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_import_hide_error_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+import "helpers/on_object.dart";
+import "helpers/on_int.dart" hide OnInt;
+
+void main() {
+ int i = 0;
+ Object o = i;
+ i.onInt;
+ //^^^^^
+ // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
+ // [cfe] The getter 'onInt' isn't defined for the class 'int'.
+ i.onObject;
+ o.onObject;
+}
diff --git a/tests/language/extension_methods/static_extension_import_hide_test.dart b/tests/language/extension_methods/static_extension_import_hide_test.dart
new file mode 100644
index 0000000..33efb80
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_import_hide_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+import "helpers/on_object.dart";
+import "helpers/on_int.dart" hide OnInt;
+
+void main() {
+ int i = 0;
+ Object o = i;
+ Expect.equals("object", i.onObject);
+ Expect.equals("object", o.onObject);
+}
diff --git a/tests/language/extension_methods/static_extension_import_prefixed_hide_error_test.dart b/tests/language/extension_methods/static_extension_import_prefixed_hide_error_test.dart
new file mode 100644
index 0000000..3c485e8
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_import_prefixed_hide_error_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+import "helpers/on_object.dart";
+import "helpers/on_int.dart" as p1 hide OnInt;
+
+void main() {
+ int i = 0;
+ Object o = i;
+ i.onInt;
+ //^^^^^
+ // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
+ // [cfe] The getter 'onInt' isn't defined for the class 'int'.
+ i.onObject;
+ o.onObject;
+}
diff --git a/tests/language/extension_methods/static_extension_import_prefixed_hide_test.dart b/tests/language/extension_methods/static_extension_import_prefixed_hide_test.dart
new file mode 100644
index 0000000..eb24f4d
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_import_prefixed_hide_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+import "helpers/on_object.dart";
+import "helpers/on_int.dart" as p1 hide OnInt;
+
+void main() {
+ int i = 0;
+ Object o = i;
+ Expect.equals("object", i.onObject);
+ Expect.equals("object", o.onObject);
+}
diff --git a/tests/language/extension_methods/static_extension_import_prefixed_show_test.dart b/tests/language/extension_methods/static_extension_import_prefixed_show_test.dart
new file mode 100644
index 0000000..caae31c
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_import_prefixed_show_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+import "helpers/on_object.dart" as p1 show OnObject;
+import "helpers/on_int.dart";
+
+void main() {
+ int i = 0;
+ Object o = i;
+ Expect.equals("int", i.onInt);
+ Expect.equals("int", i.onObject);
+ Expect.equals("object", o.onObject);
+}
diff --git a/tests/language/extension_methods/static_extension_import_prefixed_test.dart b/tests/language/extension_methods/static_extension_import_prefixed_test.dart
new file mode 100644
index 0000000..bc64023
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_import_prefixed_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+import "helpers/on_object.dart" as p1;
+import "helpers/on_int.dart";
+
+void main() {
+ int i = 0;
+ Object o = i;
+ Expect.equals("int", i.onInt);
+ Expect.equals("int", i.onObject);
+ Expect.equals("object", o.onObject);
+}
diff --git a/tests/language/extension_methods/static_extension_import_test.dart b/tests/language/extension_methods/static_extension_import_test.dart
new file mode 100644
index 0000000..2585595
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_import_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+import "helpers/on_object.dart";
+import "helpers/on_int.dart";
+
+void main() {
+ int i = 0;
+ Object o = i;
+ Expect.equals("int", i.onInt);
+ Expect.equals("int", i.onObject);
+ Expect.equals("object", o.onObject);
+}
diff --git a/tests/language/extension_methods/static_extension_import_unprefixed_show_test.dart b/tests/language/extension_methods/static_extension_import_unprefixed_show_test.dart
new file mode 100644
index 0000000..5a45148
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_import_unprefixed_show_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+import "helpers/on_object.dart" show OnObject;
+import "helpers/on_int.dart";
+
+void main() {
+ int i = 0;
+ Object o = i;
+ Expect.equals("int", i.onInt);
+ Expect.equals("int", i.onObject);
+ Expect.equals("object", o.onObject);
+}
diff --git a/tests/language/extension_methods/static_extension_inference_test.dart b/tests/language/extension_methods/static_extension_inference_test.dart
new file mode 100644
index 0000000..4e1774e
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_inference_test.dart
@@ -0,0 +1,184 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+// Tests extension method resolution type inference.
+
+import "package:expect/expect.dart";
+
+void main() {
+ List<num> numList = <int>[];
+ // Inference of E1(numList), implicit or explicit, is the same as
+ // for C1(numList), which infers `num`.
+ var numListInstance1 = C1<num>(numList);
+
+ Expect.type<List<num>>(numList.argList1);
+ sameType(numListInstance1.argDynList1, numList.argDynList1);
+ sameType(numListInstance1.selfList1, numList.selfList1);
+
+ Expect.type<List<num>>(E1(numList).argList1);
+ sameType(numListInstance1.argDynList1, E1(numList).argDynList1);
+ sameType(numListInstance1.selfList1, E1(numList).selfList1);
+
+ var numListInstance2 = C2<List<num>>(numList);
+
+ Expect.type<List<List<num>>>(numList.argList2);
+ sameType(numListInstance2.argDynList2, numList.argDynList2);
+ sameType(numListInstance2.selfList2, numList.selfList2);
+
+ Expect.type<List<List<num>>>(E2(numList).argList2);
+ sameType(numListInstance2.argDynList2, E2(numList).argDynList2);
+ sameType(numListInstance2.selfList2, E2(numList).selfList2);
+
+ Pair<int, double> pair = Pair(1, 2.5);
+ var pairInstance3 = C3<int, double>(pair);
+
+ Expect.type<List<int>>(pair.argList3);
+ Expect.type<List<double>>(pair.arg2List3);
+ sameType(pairInstance3.argDynList3, pair.argDynList3);
+ sameType(pairInstance3.arg2DynList3, pair.arg2DynList3);
+ sameType(pairInstance3.selfList3, pair.selfList3);
+
+ Expect.type<List<int>>(E3(pair).argList3);
+ Expect.type<List<double>>(E3(pair).arg2List3);
+ sameType(pairInstance3.argDynList3, E3(pair).argDynList3);
+ sameType(pairInstance3.arg2DynList3, E3(pair).arg2DynList3);
+ sameType(pairInstance3.selfList3, E3(pair).selfList3);
+
+ var pairInstance4 = C4<num>(pair);
+
+ Expect.type<List<num>>(pair.argList4);
+ sameType(pairInstance4.argDynList4, pair.argDynList4);
+ sameType(pairInstance4.selfList4, pair.selfList4);
+
+ Expect.type<List<num>>(E4(pair).argList4);
+ sameType(pairInstance4.argDynList4, E4(pair).argDynList4);
+ sameType(pairInstance4.selfList4, E4(pair).selfList4);
+
+ List<int> intList = <int>[1];
+ var intListInstance5 = C5<int>(intList);
+
+ Expect.type<List<int>>(intList.argList5);
+ sameType(intListInstance5.argDynList5, intList.argDynList5);
+ sameType(intListInstance5.selfList5, intList.selfList5);
+
+ Expect.type<List<int>>(E5(intList).argList5);
+ sameType(intListInstance5.argDynList5, E5(intList).argDynList5);
+ sameType(intListInstance5.selfList5, E5(intList).selfList5);
+}
+
+void sameType(o1, o2) {
+ Expect.equals(o1.runtimeType, o2.runtimeType);
+}
+
+extension E1<T> on List<T> {
+ List<T> get argList1 => <T>[];
+ List<Object?> get argDynList1 => <T>[];
+ List<Object?> get selfList1 {
+ var result = [this];
+ return result;
+ }
+}
+
+class C1<T> {
+ List<T> self;
+ C1(this.self);
+ List<T> get argList1 => <T>[];
+ List<Object?> get argDynList1 => <T>[];
+ List<Object?> get selfList1 {
+ var result = [self];
+ return result;
+ }
+}
+
+extension E2<T> on T {
+ List<T> get argList2 => <T>[];
+ List<Object?> get argDynList2 => <T>[];
+ List<Object?> get selfList2 {
+ var result = [this];
+ return result;
+ }
+}
+
+class C2<T> {
+ T self;
+ C2(this.self);
+ List<T> get argList2 => <T>[];
+ List<Object?> get argDynList2 => <T>[];
+ List<Object?> get selfList2 {
+ var result = [self];
+ return result;
+ }
+}
+
+extension E3<S, T> on Pair<T, S> {
+ List<T> get argList3 => <T>[];
+ List<Object?> get argDynList3 => <T>[];
+ List<S> get arg2List3 => <S>[];
+ List<Object?> get arg2DynList3 => <S>[];
+ List<Object?> get selfList3 {
+ var result = [this];
+ return result;
+ }
+}
+
+class C3<T, S> {
+ Pair<T, S> self;
+ C3(this.self);
+ List<T> get argList3 => <T>[];
+ List<Object?> get argDynList3 => <T>[];
+ List<S> get arg2List3 => <S>[];
+ List<Object?> get arg2DynList3 => <S>[];
+ List<Object?> get selfList3 {
+ var result = [self];
+ return result;
+ }
+}
+
+extension E4<T> on Pair<T, T> {
+ List<T> get argList4 => <T>[];
+ List<Object?> get argDynList4 => <T>[];
+ List<Object?> get selfList4 {
+ var result = [this];
+ return result;
+ }
+}
+
+class C4<T> {
+ Pair<T, T> self;
+ C4(this.self);
+ List<T> get argList4 => <T>[];
+ List<Object?> get argDynList4 => <T>[];
+ List<Object?> get selfList4 {
+ var result = [self];
+ return result;
+ }
+}
+
+extension E5<T extends num> on List<T> {
+ List<T> get argList5 => <T>[];
+ List<Object?> get argDynList5 => <T>[];
+ List<Object?> get selfList5 {
+ var result = [this];
+ return result;
+ }
+}
+
+class C5<T extends num> {
+ List<T> self;
+ C5(this.self);
+ List<T> get argList5 => <T>[];
+ List<Object?> get argDynList5 => <T>[];
+ List<Object?> get selfList5 {
+ var result = [self];
+ return result;
+ }
+}
+
+class Pair<A, B> {
+ final A first;
+ final B second;
+ Pair(this.first, this.second);
+}
diff --git a/tests/language/extension_methods/static_extension_internal_basename_shadowing_error_test.dart b/tests/language/extension_methods/static_extension_internal_basename_shadowing_error_test.dart
new file mode 100644
index 0000000..5c5c1c7
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_internal_basename_shadowing_error_test.dart
@@ -0,0 +1,505 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+///////////////////////////////////////////////////////////////////////
+// The following tests check that setters or getters in an extension
+// correctly shadow members with the same basename in the surrounding
+// scope.
+///////////////////////////////////////////////////////////////////////
+
+int get topLevelGetter => -1;
+void set topLevelSetter(int _) {}
+int topLevelField = -3;
+int topLevelMethod(int x) => -4;
+
+// Check that an instance getter in an extension shadows top level
+// members with the same basename.
+extension E1 on A1 {
+ int get topLevelSetter => 1;
+ int get topLevelField => 2;
+ int get topLevelMethod => 3;
+ void test() {
+ // The instance getter shadows the global setter
+ topLevelSetter = topLevelSetter + 1;
+// ^^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] Setter not found: 'topLevelSetter'.
+ topLevelSetter++;
+// ^^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] Setter not found: 'topLevelSetter'.
+ topLevelSetter = 0;
+// ^^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] Setter not found: 'topLevelSetter'.
+
+ // The instance getter shadows the global field setter
+ topLevelField = topLevelField + 1;
+// ^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] Setter not found: 'topLevelField'.
+ topLevelField++;
+// ^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] Setter not found: 'topLevelField'.
+ topLevelField = 0;
+// ^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] Setter not found: 'topLevelField'.
+
+ // The instance getter shadows the global method
+ topLevelMethod(4);
+// ^^^^^^^^^^^^^^
+// [analyzer] STATIC_TYPE_WARNING.INVOCATION_OF_NON_FUNCTION_EXPRESSION
+// ^
+// [cfe] The method 'call' isn't defined for the class 'int'.
+ }
+}
+
+class A1 {}
+
+// Check that an instance setter in an extension shadows top level
+// members with the same basename.
+extension E2 on A2 {
+ void set topLevelGetter(int _) {}
+ void set topLevelField(int _) {}
+ void set topLevelMethod(int _) {}
+ void test() {
+ // The instance setter shadows the global getter
+ topLevelGetter = topLevelGetter + 1;
+// ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'topLevelGetter'.
+ topLevelGetter++;
+// ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'topLevelGetter'.
+ topLevelGetter;
+// ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'topLevelGetter'.
+ topLevelGetter = 3;
+
+ // The instance setter shadows the global field getter
+ topLevelField = topLevelField + 1;
+// ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'topLevelField'.
+ topLevelField++;
+// ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'topLevelField'.
+ topLevelField;
+// ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'topLevelField'.
+
+ // The instance setter shadows the global method
+ topLevelMethod(4);
+// ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'topLevelMethod'.
+ }
+}
+
+class A2 {}
+
+// Check that a static getter in an extension shadows top level
+// members with the same basename.
+extension E3 on A3 {
+ static int get topLevelSetter => 1;
+ static int get topLevelField => 2;
+ static int get topLevelMethod => 3;
+ void test() {
+ // The static getter shadows the global setter
+ topLevelSetter = topLevelSetter + 1;
+// ^^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] Setter not found: 'topLevelSetter'.
+ topLevelSetter++;
+// ^^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] Setter not found: 'topLevelSetter'.
+ topLevelSetter = 0;
+// ^^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] Setter not found: 'topLevelSetter'.
+
+ // The static getter shadows the global field setter
+ topLevelField = topLevelField + 1;
+// ^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] Setter not found: 'topLevelField'.
+ topLevelField++;
+// ^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] Setter not found: 'topLevelField'.
+ topLevelField = 0;
+// ^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] Setter not found: 'topLevelField'.
+
+ // The static getter shadows the global method
+ topLevelMethod(4);
+// ^^^^^^^^^^^^^^
+// [analyzer] STATIC_TYPE_WARNING.INVOCATION_OF_NON_FUNCTION_EXPRESSION
+// ^
+// [cfe] The method 'call' isn't defined for the class 'int'.
+ }
+}
+
+class A3 {}
+
+// Check that a static setter in an extension shadows top level
+// members with the same basename.
+extension E4 on A4 {
+ static void set topLevelGetter(int _) {}
+ static void set topLevelField(int _) {}
+ static void set topLevelMethod(int _) {}
+ void test() {
+ // The static setter shadows the global getter
+ topLevelGetter = topLevelGetter + 1;
+// ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'topLevelGetter'.
+ topLevelGetter++;
+// ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'topLevelGetter'.
+ topLevelGetter;
+// ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'topLevelGetter'.
+
+ // The static setter shadows the global field getter
+ topLevelField = topLevelField + 1;
+// ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'topLevelField'.
+ topLevelField++;
+// ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'topLevelField'.
+ topLevelField;
+// ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'topLevelField'.
+
+ // The static setter shadows the global method
+ topLevelMethod(4);
+// ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'topLevelMethod'.
+ }
+}
+
+class A4 {}
+
+// Define extensions on A6.
+extension E5 on A6 {
+ void set extensionSetter(int _) {}
+ int extensionMethod(int x) => -3;
+}
+
+// Check that an instance getter in an extension shadows extension
+// members with the same basename from a different extension.
+extension E6 on A6 {
+ int get extensionSetter => 1;
+ int get extensionMethod => 3;
+ void test() {
+ // The instance getter shadows the other extension's setter
+ extensionSetter = extensionSetter + 1;
+// ^^^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] Setter not found: 'extensionSetter'.
+ extensionSetter++;
+// ^^^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] Setter not found: 'extensionSetter'.
+ extensionSetter = 0;
+// ^^^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] Setter not found: 'extensionSetter'.
+
+ // The instance getter shadows the other extensions method
+ extensionMethod(4);
+// ^^^^^^^^^^^^^^^
+// [analyzer] STATIC_TYPE_WARNING.INVOCATION_OF_NON_FUNCTION_EXPRESSION
+// ^
+// [cfe] The method 'call' isn't defined for the class 'int'.
+ }
+}
+
+class A6 {}
+
+// Check that an instance getter in a class shadows extension
+// members with the same basename from extension E5.
+class A7 extends A6 {
+ int get extensionSetter => 1;
+ int get extensionMethod => 3;
+ void test() {
+ // The instance getter shadows the other extension's setter
+ extensionSetter = extensionSetter + 1;
+// ^^^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] The setter 'extensionSetter' isn't defined for the class 'A7'.
+ extensionSetter++;
+// ^^^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] The setter 'extensionSetter' isn't defined for the class 'A7'.
+ extensionSetter = 0;
+// ^^^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] The setter 'extensionSetter' isn't defined for the class 'A7'.
+
+ // The instance getter shadows the other extensions method
+ extensionMethod(4);
+// ^^^^^^^^^^^^^^^
+// [analyzer] STATIC_TYPE_WARNING.INVOCATION_OF_NON_FUNCTION_EXPRESSION
+// ^
+// [cfe] 'extensionMethod' isn't a function or method and can't be invoked.
+ }
+}
+
+// Define extensions on A8.
+extension E7 on A8 {
+ int get extensionGetter => -1;
+ int extensionMethod(int x) => -3;
+}
+
+// Check that an instance setter in an extension shadows extension
+// members with the same basename from a different extension.
+extension E8 on A8 {
+ void set extensionGetter(int _) {}
+ void set extensionMethod(int _) {}
+ void test() {
+ // The instance setter shadows the other extension's getter
+ extensionGetter = extensionGetter + 1;
+// ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'extensionGetter'.
+ extensionGetter++;
+// ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'extensionGetter'.
+ extensionGetter;
+// ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'extensionGetter'.
+
+ // The instance setter shadows the other extension's method.
+ extensionMethod(4);
+// ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'extensionMethod'.
+ }
+}
+
+class A8 {}
+
+// Check that an instance setter in a class shadows extension
+// members with the same basename from extension E7.
+class A9 extends A8 {
+ void set extensionGetter(int _) {}
+ void set extensionMethod(int _) {}
+ void test() {
+ // The instance setter shadows the other extension's getter
+ extensionGetter = extensionGetter + 1;
+// ^^
+// [analyzer] unspecified
+// [cfe] The getter 'extensionGetter' isn't defined for the class 'A9'.
+ extensionGetter++;
+// ^^
+// [analyzer] unspecified
+// [cfe] The getter 'extensionGetter' isn't defined for the class 'A9'.
+ extensionGetter;
+// ^^
+// [analyzer] unspecified
+// [cfe] The getter 'extensionGetter' isn't defined for the class 'A9'.
+
+ // The instance setter shadows the other extension's method.
+ extensionMethod(4);
+// ^^
+// [analyzer] unspecified
+// [cfe] The method 'extensionMethod' isn't defined for the class 'A9'.
+ }
+}
+
+// Define extensions on A10.
+extension E9 on A10 {
+ void set extensionSetter(int _) {}
+ void set extensionFieldSetter(int _) {}
+ int extensionMethod(int x) => -3;
+}
+
+// Check that a static getter in an extension shadows extension
+// members with the same basename from a different extension.
+extension E10 on A10 {
+ static int get extensionSetter => 1;
+ static final int extensionFieldSetter = 2;
+ static int get extensionMethod => 3;
+ void test() {
+ // The static getter shadows the other extension's setter
+ extensionSetter = extensionSetter + 1;
+// ^^^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] Setter not found: 'extensionSetter'.
+ extensionSetter++;
+// ^^^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] Setter not found: 'extensionSetter'.
+ extensionSetter = 0;
+// ^^^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] Setter not found: 'extensionSetter'.
+
+ // The static field shadows the other extension's setter
+ extensionFieldSetter = extensionFieldSetter + 1;
+// ^^
+// [analyzer] unspecified
+// [cfe] Setter not found: 'extensionFieldSetter'.
+ extensionFieldSetter++;
+// ^^
+// [analyzer] unspecified
+// [cfe] Setter not found: 'extensionFieldSetter'.
+ extensionFieldSetter = 0;
+// ^^
+// [analyzer] unspecified
+// [cfe] Setter not found: 'extensionFieldSetter'.
+
+ // The static getter shadows the other extensions method
+ extensionMethod(4);
+// ^^^^^^^^^^^^^^^
+// [analyzer] STATIC_TYPE_WARNING.INVOCATION_OF_NON_FUNCTION_EXPRESSION
+// ^
+// [cfe] The method 'call' isn't defined for the class 'int'.
+ }
+}
+
+class A10 {}
+
+// Check that a static getter in a class shadows extension
+// members with the same basename from extension E9.
+class A11 extends A10 {
+ static int get extensionSetter => 1;
+ static final int extensionFieldSetter = 2;
+ static int get extensionMethod => 3;
+ void test() {
+ // The static getter shadows the other extension's setter
+ extensionSetter = extensionSetter + 1;
+// ^^^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] Setter not found: 'extensionSetter'.
+ extensionSetter++;
+// ^^^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] Setter not found: 'extensionSetter'.
+ extensionSetter = 0;
+// ^^^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+// [cfe] Setter not found: 'extensionSetter'.
+
+ // The static field shadows the other extension's setter
+ extensionFieldSetter = extensionFieldSetter + 1;
+// ^^
+// [analyzer] unspecified
+// [cfe] Setter not found: 'extensionFieldSetter'.
+ extensionFieldSetter++;
+// ^^
+// [analyzer] unspecified
+// [cfe] Setter not found: 'extensionFieldSetter'.
+ extensionFieldSetter = 0;
+// ^^
+// [analyzer] unspecified
+// [cfe] Setter not found: 'extensionFieldSetter'.
+
+ // The static getter shadows the other extensions method
+ extensionMethod(4);
+// ^^^^^^^^^^^^^^^
+// [analyzer] STATIC_TYPE_WARNING.INVOCATION_OF_NON_FUNCTION_EXPRESSION
+// ^
+// [cfe] The method 'call' isn't defined for the class 'int'.
+ }
+}
+
+// Define extensions on A12.
+extension E11 on A12 {
+ int get extensionGetter => -1;
+ int extensionMethod(int x) => -3;
+}
+
+// Check that a static setter in an extension shadows extension
+// members with the same basename from a different extension.
+extension E12 on A12 {
+ static void set extensionGetter(int _) {}
+ static void set extensionMethod(int _) {}
+ void test() {
+ // The static setter shadows the other extension's getter
+ extensionGetter = extensionGetter + 1;
+// ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'extensionGetter'.
+ extensionGetter++;
+// ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'extensionGetter'.
+ extensionGetter;
+// ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'extensionGetter'.
+
+ // The static setter shadows the other extension's method.
+ extensionMethod(4);
+// ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'extensionMethod'.
+ }
+}
+
+class A12 {}
+
+// Check that a static setter in a class shadows extension
+// members with the same basename from extension E11.
+class A13 extends A12 {
+ static void set extensionGetter(int _) {}
+ static void set extensionMethod(int _) {}
+ void test() {
+ // The static setter shadows the other extension's getter
+ extensionGetter = extensionGetter + 1;
+// ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'extensionGetter'.
+ extensionGetter++;
+// ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'extensionGetter'.
+ extensionGetter;
+// ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'extensionGetter'.
+
+ // The static setter shadows the other extension's method.
+ extensionMethod(4);
+// ^^
+// [analyzer] unspecified
+// [cfe] Getter not found: 'extensionMethod'.
+ }
+}
+
+void main() {
+ A1().test();
+ A2().test();
+ A3().test();
+ A4().test();
+ A6().test();
+ A7().test();
+ A8().test();
+ A9().test();
+ A10().test();
+ A11().test();
+ A12().test();
+ A13().test();
+}
diff --git a/tests/language/extension_methods/static_extension_internal_basename_shadowing_test.dart b/tests/language/extension_methods/static_extension_internal_basename_shadowing_test.dart
new file mode 100644
index 0000000..659bcc2
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_internal_basename_shadowing_test.dart
@@ -0,0 +1,276 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+import "package:expect/expect.dart";
+
+///////////////////////////////////////////////////////////////////////
+// The following tests check that setters or getters in an extension
+// correctly shadow members with the same basename in the surrounding
+// scope.
+///////////////////////////////////////////////////////////////////////
+
+String get topLevelGetter => "-1";
+void set topLevelSetter(String _) {}
+String topLevelField = "-3";
+String topLevelMethod(String x) => "-4";
+
+// Location that extension setters write to.
+int? _storeTo = null;
+// Check that the most recent setter call set the value
+// of _storeTo.
+void checkSetter(int x) {
+ int? written = _storeTo;
+ _storeTo = null;
+ Expect.equals(written, x);
+}
+
+// Check that an instance getter in an extension shadows top level
+// members with the same basename.
+extension E1 on A1 {
+ int get topLevelSetter => 1;
+ int get topLevelField => 2;
+ int get topLevelMethod => 3;
+ void test() {
+ // Reading the local getters is valid
+ Expect.equals(topLevelSetter + 1, 2);
+ Expect.equals(topLevelField + 1, 3);
+ Expect.equals(topLevelMethod + 1, 4);
+ }
+}
+
+class A1 {}
+
+// Check that an instance setter in an extension shadows top level
+// members with the same basename.
+extension E2 on A2 {
+ void set topLevelGetter(int x) {
+ _storeTo = x;
+ }
+
+ void set topLevelField(int x) {
+ _storeTo = x;
+ }
+
+ void set topLevelMethod(int x) {
+ _storeTo = x;
+ }
+
+ void test() {
+ checkSetter(topLevelGetter = 42);
+ checkSetter(topLevelField = 42);
+ checkSetter(topLevelMethod = 42);
+ }
+}
+
+class A2 {}
+
+// Check that a static getter in an extension shadows top level
+// members with the same basename.
+extension E3 on A3 {
+ static int get topLevelSetter => 1;
+ static int get topLevelField => 2;
+ static int get topLevelMethod => 3;
+ void test() {
+ // Reading the local getters is valid
+ Expect.equals(topLevelSetter + 1, 2);
+ Expect.equals(topLevelField + 1, 3);
+ Expect.equals(topLevelMethod + 1, 4);
+ }
+}
+
+class A3 {}
+
+// Check that a static setter in an extension shadows top level
+// members with the same basename.
+extension E4 on A4 {
+ static void set topLevelGetter(int x) {
+ _storeTo = x;
+ }
+
+ static void set topLevelField(int x) {
+ _storeTo = x;
+ }
+
+ static void set topLevelMethod(int x) {
+ _storeTo = x;
+ }
+
+ void test() {
+ checkSetter(topLevelGetter = 42);
+ checkSetter(topLevelField = 42);
+ checkSetter(topLevelMethod = 42);
+ }
+}
+
+class A4 {}
+
+// Define extensions on A6.
+extension E5 on A6 {
+ void set extensionSetter(int x) {}
+ int extensionMethod(int x) => -3;
+}
+
+// Check that an instance getter in an extension shadows extension
+// members with the same basename from a different extension.
+extension E6 on A6 {
+ int get extensionSetter => 1;
+ int get extensionMethod => 3;
+ void test() {
+ // Reading the local getters is valid
+ Expect.equals(extensionSetter + 1, 2);
+ Expect.equals(extensionMethod + 1, 4);
+ }
+}
+
+class A6 {}
+
+// Check that an instance getter in a class shadows extension
+// members with the same basename from extension E5.
+class A7 extends A6 {
+ int get extensionSetter => 1;
+ int get extensionMethod => 3;
+ void test() {
+ // Reading the local getters is valid
+ Expect.equals(extensionSetter + 1, 2);
+ Expect.equals(extensionMethod + 1, 4);
+ }
+}
+
+// Define extensions on A8.
+extension E7 on A8 {
+ int get extensionGetter => -1;
+ int extensionMethod(int x) => -3;
+}
+
+// Check that an instance setter in an extension shadows extension
+// members with the same basename from a different extension.
+extension E8 on A8 {
+ void set extensionGetter(int x) {
+ _storeTo = x;
+ }
+
+ void set extensionMethod(int x) {
+ _storeTo = x;
+ }
+
+ void test() {
+ checkSetter(extensionGetter = 42);
+ checkSetter(extensionMethod = 42);
+ }
+}
+
+class A8 {}
+
+// Check that an instance setter in a class shadows extension
+// members with the same basename from extension E7.
+class A9 extends A8 {
+ void set extensionGetter(int x) {
+ _storeTo = x;
+ }
+
+ void set extensionMethod(int x) {
+ _storeTo = x;
+ }
+
+ void test() {
+ checkSetter(extensionGetter = 42);
+ checkSetter(extensionMethod = 42);
+ }
+}
+
+// Define extensions on A10.
+extension E9 on A10 {
+ void set extensionSetter(int x) {}
+ void set extensionFieldSetter(int x) {}
+ int extensionMethod(int x) => -3;
+}
+
+// Check that a static getter in an extension shadows extension
+// members with the same basename from a different extension.
+extension E10 on A10 {
+ static int get extensionSetter => 1;
+ static final int extensionFieldSetter = 2;
+ static int get extensionMethod => 3;
+ void test() {
+ // Reading the local getters is valid
+ Expect.equals(extensionSetter + 1, 2);
+ Expect.equals(extensionFieldSetter + 1, 3);
+ Expect.equals(extensionMethod + 1, 4);
+ }
+}
+
+class A10 {}
+
+// Check that a static getter in a class shadows extension
+// members with the same basename from extension E9.
+class A11 extends A10 {
+ static int get extensionSetter => 1;
+ static final int extensionFieldSetter = 2;
+ static int get extensionMethod => 3;
+ void test() {
+ // Reading the local getters is valid
+ Expect.equals(extensionSetter + 1, 2);
+ Expect.equals(extensionFieldSetter + 1, 3);
+ Expect.equals(extensionMethod + 1, 4);
+ }
+}
+
+// Define extensions on A12.
+extension E11 on A12 {
+ int get extensionGetter => -1;
+ int extensionMethod(int x) => -3;
+}
+
+// Check that a static setter in an extension shadows extension
+// members with the same basename from a different extension.
+extension E12 on A12 {
+ static void set extensionGetter(int x) {
+ _storeTo = x;
+ }
+
+ static void set extensionMethod(int x) {
+ _storeTo = x;
+ }
+
+ void test() {
+ checkSetter(extensionGetter = 42);
+ checkSetter(extensionMethod = 42);
+ }
+}
+
+class A12 {}
+
+// Check that a static setter in a class shadows extension
+// members with the same basename from extension E11.
+class A13 extends A12 {
+ static void set extensionGetter(int x) {
+ _storeTo = x;
+ }
+
+ static void set extensionMethod(int x) {
+ _storeTo = x;
+ }
+
+ void test() {
+ checkSetter(extensionGetter = 42);
+ checkSetter(extensionMethod = 42);
+ }
+}
+
+void main() {
+ A1().test();
+ A2().test();
+ A3().test();
+ A4().test();
+ A6().test();
+ A7().test();
+ A8().test();
+ A9().test();
+ A10().test();
+ A11().test();
+ A12().test();
+ A13().test();
+}
diff --git a/tests/language/extension_methods/static_extension_internal_name_conflict_error_test.dart b/tests/language/extension_methods/static_extension_internal_name_conflict_error_test.dart
new file mode 100644
index 0000000..a284784
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_internal_name_conflict_error_test.dart
@@ -0,0 +1,258 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+// Tests that errors are given for internal name conflicts in extension methods.
+
+// It is an error to have duplicate type parameter names.
+extension E1<T, T> on int {
+// ^
+// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+// [cfe] A type variable can't have the same name as another.
+}
+
+extension E2 on int {}
+
+// It is an error to have duplicate extension names.
+extension E2 on int {}
+// ^^
+// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+// [cfe] 'E2' is already declared in this scope.
+
+class E2 {}
+// ^^
+// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+// [cfe] 'E2' is already declared in this scope.
+
+typedef E2 = int Function(int);
+// ^^
+// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+// [cfe] 'E2' is already declared in this scope.
+
+void E2(int x) {}
+// ^^
+// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+// [cfe] 'E2' is already declared in this scope.
+
+int E2 = 3;
+// ^^
+// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+// [cfe] 'E2' is already declared in this scope.
+
+////////////////////////////////////////////////////////////////////
+// It is an error to have two static members with the same base name
+// unless one is a setter and one is a getter.
+//
+// The next set of tests check various combinations of member name
+// conflicts: first testing that members of the same kind (e.g.
+// method/method) induce conflicts for the various combinations of
+// static/instance; and then testing that members of different kind (e.g.
+// method/getter) induce conflicts for the various combinations of
+// static/instance.
+////////////////////////////////////////////////////////////////////
+
+// Check static members colliding with static members (of the same kind)
+extension E3 on int {
+ static int method() => 0;
+ static int get property => 1;
+ static void set property(int value) {}
+ static int field = 3;
+ static int field2 = 4;
+
+ static int method() => 0;
+ // ^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+ // [cfe] 'method' is already declared in this scope.
+ static int get property => 1;
+ // ^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+ // [cfe] 'property' is already declared in this scope.
+ static void set property(int value) {}
+ // ^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+ // [cfe] 'property' is already declared in this scope.
+ static int field = 3;
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+ // [cfe] 'field' is already declared in this scope.
+ static int get field2 => 1;
+ // ^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+ // [cfe] 'field2' is already declared in this scope.
+ static void set field2(int value) {}
+ // ^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+}
+
+// Check instance members colliding with instance members (of the same kind).
+extension E4 on int {
+ int method() => 0;
+ int get property => 1;
+ void set property(int value) {}
+
+ int method() => 0;
+ // ^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+ // [cfe] 'method' is already declared in this scope.
+ int get property => 1;
+ // ^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+ // [cfe] 'property' is already declared in this scope.
+ void set property(int value) {}
+ // ^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+ // [cfe] 'property' is already declared in this scope.
+}
+
+// Check static members colliding with static members (of the same kind).
+extension E5 on int {
+ static int method() => 0;
+ // ^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+ static int get property => 1;
+ // ^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+ static void set property(int value) {}
+ // ^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+ static int get property2 => 1;
+ // ^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+ // [cfe] Conflicts with setter 'property2'.
+ static void set property3(int x) {}
+ // ^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+ // [cfe] Conflicts with member 'property3'.
+ static int field = 3;
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+ // [cfe] Conflicts with setter 'field'.
+ static int field2 = 3;
+ // ^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+
+ int method() => 0;
+ // ^
+ // [cfe] 'method' is already declared in this scope.
+ int get property => 1;
+ // ^
+ // [cfe] 'property' is already declared in this scope.
+ void set property(int value) {}
+ // ^
+ // [cfe] 'property' is already declared in this scope.
+ void set property2(int value) {}
+ // ^
+ // [cfe] Conflicts with member 'property2'.
+ int get property3 => 1;
+ // ^
+ // [cfe] Conflicts with setter 'property3'.
+ void set field(int value) {}
+ // ^
+ // [cfe] Conflicts with member 'field'.
+ int get field2 => 1;
+ // ^
+ // [cfe] 'field2' is already declared in this scope.
+}
+
+// Check a static method colliding with a static getter.
+extension E6 on int {
+ static int method() => 0;
+ static int get method => 1;
+ // ^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+ // [cfe] 'method' is already declared in this scope.
+}
+
+// Check a static method colliding with a static setter.
+extension E7 on int {
+ static int method() => 0;
+ // ^
+ // [cfe] Conflicts with setter 'method'.
+ static void set method(int value) {}
+ // ^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+ // [cfe] Conflicts with member 'method'.
+}
+
+// Check a static method colliding with a static field.
+extension E8 on int {
+ static int method() => 0;
+ static int method = 3;
+ // ^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+ // [cfe] 'method' is already declared in this scope.
+}
+
+// Check an instance method colliding with an instance getter.
+extension E9 on int {
+ int method() => 0;
+ int get method => 1;
+ // ^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+ // [cfe] 'method' is already declared in this scope.
+}
+
+// Check an instance method colliding with an instance setter.
+extension E10 on int {
+ int method() => 0;
+ // ^
+ // [cfe] Conflicts with setter 'method'.
+ void set method(int value) {}
+ // ^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+ // [cfe] Conflicts with member 'method'.
+}
+
+// Check a static method colliding with an instance getter.
+extension E11 on int {
+ static int method() => 0;
+ // ^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+ int get method => 1;
+ // ^
+ // [cfe] 'method' is already declared in this scope.
+}
+
+// Check a static method colliding with an instance setter.
+extension E12 on int {
+ static int method() => 0;
+ // ^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+ // [cfe] Conflicts with setter 'method'.
+ void set method(int value) {}
+ // ^
+ // [cfe] Conflicts with member 'method'.
+}
+
+// Check an instance method colliding with a static getter.
+extension E13 on int {
+ int method() => 0;
+ static int get method => 1;
+ // ^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+ // [cfe] 'method' is already declared in this scope.
+}
+
+// Check an instance method colliding with a static setter.
+extension E14 on int {
+ int method() => 0;
+ // ^
+ // [cfe] Conflicts with setter 'method'.
+ static void set method(int value) {}
+ // ^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+ // [cfe] Conflicts with member 'method'.
+}
+
+// Check an instance method colliding with a static field.
+extension E15 on int {
+ int method() => 0;
+ static int method = 3;
+ // ^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+ // [cfe] 'method' is already declared in this scope.
+}
+
+void main() {}
diff --git a/tests/language/extension_methods/static_extension_internal_resolution_0_test.dart b/tests/language/extension_methods/static_extension_internal_resolution_0_test.dart
new file mode 100644
index 0000000..418ba2b
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_internal_resolution_0_test.dart
@@ -0,0 +1,208 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+// Tests resolution of identifiers inside of extension methods
+
+// Test an extension MyExt with no members against:
+// - a class A with only its own members
+// - and another extension ExtraExt with only its own members
+
+import "package:expect/expect.dart";
+
+/////////////////////////////////////////////////////////////////////////
+// Note: These imports may be deliberately unused. They bring certain
+// names into scope, in order to test that certain resolution choices are
+// made even in the presence of other symbols.
+/////////////////////////////////////////////////////////////////////////
+
+// Do Not Delete.
+// Bring global members into scope.
+import "helpers/global_scope.dart";
+
+// Do Not Delete.
+// Bring a class A with instance members into scope.
+import "helpers/class_no_shadow.dart";
+
+// Do Not Delete.
+// Bring an extension ExtraExt with no overlapping symbols into scope.
+import "helpers/extension_only.dart";
+
+const bool extensionValue = true;
+
+// An extension which defines no members of its own
+extension MyExt on A {
+ void testNakedIdentifiers() {
+ // Globals should resolve to the global name space, and not to the members
+ // of the other extension (when present)
+ {
+ int t0 = fieldInGlobalScope;
+ checkGlobalValue(t0);
+ int t1 = getterInGlobalScope;
+ checkGlobalValue(t1);
+ setterInGlobalScope = globalValue;
+ int t2 = methodInGlobalScope();
+ checkGlobalValue(t2);
+ }
+
+ // Instance members resolve to the instance methods and not the members
+ // of the other extension (when present)
+ {
+ String t0 = fieldInInstanceScope;
+ checkInstanceValue(t0);
+ String t1 = getterInInstanceScope;
+ checkInstanceValue(t0);
+ setterInInstanceScope = instanceValue;
+ String t2 = methodInInstanceScope();
+ checkInstanceValue(t0);
+ }
+
+ // Extension members resolve to the extension methods in the other
+ // extension (unresolved identifier "id" gets turned into "this.id",
+ // which is then subject to extension method lookup).
+ {
+ double t0 = fieldInOtherExtensionScope;
+ checkOtherExtensionValue(t0);
+ double t1 = getterInOtherExtensionScope;
+ checkOtherExtensionValue(t1);
+ setterInOtherExtensionScope = otherExtensionValue;
+ double t2 = methodInOtherExtensionScope();
+ checkOtherExtensionValue(t2);
+ }
+ }
+
+ void testIdentifiersOnThis() {
+ // Instance members resolve to the instance methods and not the members
+ // of the other extension (when present)
+ {
+ String t0 = this.fieldInInstanceScope;
+ checkInstanceValue(t0);
+ String t1 = this.getterInInstanceScope;
+ checkInstanceValue(t0);
+ this.setterInInstanceScope = instanceValue;
+ String t2 = this.methodInInstanceScope();
+ checkInstanceValue(t0);
+ }
+
+ // Extension members resolve to the extension methods in the other
+ // extension.
+ {
+ double t0 = this.fieldInOtherExtensionScope;
+ checkOtherExtensionValue(t0);
+ double t1 = this.getterInOtherExtensionScope;
+ checkOtherExtensionValue(t1);
+ this.setterInOtherExtensionScope = otherExtensionValue;
+ double t2 = this.methodInOtherExtensionScope();
+ checkOtherExtensionValue(t2);
+ }
+ }
+
+ void testIdentifiersOnInstance() {
+ A self = this;
+
+ // Instance members resolve to the instance methods and not the members
+ // of the other extension (when present)
+ {
+ String t0 = self.fieldInInstanceScope;
+ checkInstanceValue(t0);
+ String t1 = self.getterInInstanceScope;
+ checkInstanceValue(t1);
+ self.setterInInstanceScope = instanceValue;
+ String t2 = self.methodInInstanceScope();
+ checkInstanceValue(t2);
+ }
+
+ // Extension members resolve to the extension methods in the other
+ // extension.
+ {
+ double t0 = self.fieldInOtherExtensionScope;
+ checkOtherExtensionValue(t0);
+ double t1 = self.getterInOtherExtensionScope;
+ checkOtherExtensionValue(t1);
+ self.setterInOtherExtensionScope = otherExtensionValue;
+ double t2 = self.methodInOtherExtensionScope();
+ checkOtherExtensionValue(t2);
+ }
+ }
+
+ void instanceTest() {
+ MyExt(this).testNakedIdentifiers();
+ MyExt(this).testIdentifiersOnThis();
+ MyExt(this).testIdentifiersOnInstance();
+ }
+}
+
+class B extends A {
+ void testNakedIdentifiers() {
+ // Globals should resolve to the global name space, and not to the members
+ // of the other extension (when present)
+ {
+ int t0 = fieldInGlobalScope;
+ checkGlobalValue(t0);
+ int t1 = getterInGlobalScope;
+ checkGlobalValue(t1);
+ setterInGlobalScope = globalValue;
+ int t2 = methodInGlobalScope();
+ checkGlobalValue(t2);
+ }
+
+ // Instance members resolve to the instance methods and not the members
+ // of the other extension (when present)
+ {
+ String t0 = fieldInInstanceScope;
+ checkInstanceValue(t0);
+ String t1 = getterInInstanceScope;
+ checkInstanceValue(t0);
+ setterInInstanceScope = instanceValue;
+ String t2 = methodInInstanceScope();
+ checkInstanceValue(t0);
+ }
+
+ // Extension members resolve to the extension methods in the other
+ // extension (unresolved identifier "id" gets turned into "this.id",
+ // which is then subject to extension method lookup).
+ {
+ double t0 = fieldInOtherExtensionScope;
+ checkOtherExtensionValue(t0);
+ double t1 = getterInOtherExtensionScope;
+ checkOtherExtensionValue(t1);
+ setterInOtherExtensionScope = otherExtensionValue;
+ double t2 = methodInOtherExtensionScope();
+ checkOtherExtensionValue(t2);
+ }
+ }
+}
+
+void main() {
+ var a = new A();
+ a.instanceTest();
+ new B().testNakedIdentifiers();
+
+ // Check external resolution as well while we're here
+
+ // Instance members resolve to the instance methods and not the members
+ // of the other extension (when present)
+ {
+ String t0 = a.fieldInInstanceScope;
+ checkInstanceValue(t0);
+ String t1 = a.getterInInstanceScope;
+ checkInstanceValue(t1);
+ a.setterInInstanceScope = instanceValue;
+ String t2 = a.methodInInstanceScope();
+ checkInstanceValue(t2);
+ }
+
+ // Extension members resolve to the extension methods in the other
+ // extension.
+ {
+ double t0 = a.fieldInOtherExtensionScope;
+ checkOtherExtensionValue(t0);
+ double t1 = a.getterInOtherExtensionScope;
+ checkOtherExtensionValue(t1);
+ a.setterInOtherExtensionScope = otherExtensionValue;
+ double t2 = a.methodInOtherExtensionScope();
+ checkOtherExtensionValue(t2);
+ }
+}
diff --git a/tests/language/extension_methods/static_extension_internal_resolution_1_test.dart b/tests/language/extension_methods/static_extension_internal_resolution_1_test.dart
new file mode 100644
index 0000000..052ab86
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_internal_resolution_1_test.dart
@@ -0,0 +1,244 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+// Tests resolution of identifiers inside of extension methods
+
+// Test an extension MyExt with no members against:
+// - a class A with only its own members
+// - and an extension ExtraExt which overlaps the global and class members
+
+import "package:expect/expect.dart";
+
+/////////////////////////////////////////////////////////////////////////
+// Note: These imports may be deliberately unused. They bring certain
+// names into scope, in order to test that certain resolution choices are
+// made even in the presence of other symbols.
+/////////////////////////////////////////////////////////////////////////
+
+// Do Not Delete.
+// Bring global members into scope.
+import "helpers/global_scope.dart";
+
+// Do Not Delete.
+// Bring a class A with instance members into scope.
+import "helpers/class_no_shadow.dart";
+
+// Do Not Delete.
+// Bring an extension ExtraExt that overlaps the global and instance names
+// into scope.
+import "helpers/extension_global_instance.dart";
+
+const bool extensionValue = true;
+
+// An extension which defines no members of its own
+extension MyExt on A {
+ void testNakedIdentifiers() {
+ // Globals should resolve to the global name space, and not to the members
+ // of the other extension (when present)
+ {
+ int t0 = fieldInGlobalScope;
+ checkGlobalValue(t0);
+ int t1 = getterInGlobalScope;
+ checkGlobalValue(t1);
+ setterInGlobalScope = globalValue;
+ int t2 = methodInGlobalScope();
+ checkGlobalValue(t2);
+ }
+
+ // Instance members resolve to the instance methods and not the members
+ // of the other extension (when present)
+ {
+ String t0 = fieldInInstanceScope;
+ checkInstanceValue(t0);
+ String t1 = getterInInstanceScope;
+ checkInstanceValue(t0);
+ setterInInstanceScope = instanceValue;
+ String t2 = methodInInstanceScope();
+ checkInstanceValue(t0);
+ }
+
+ // Extension members resolve to the extension methods in the other
+ // extension (unresolved identifier "id" gets turned into "this.id",
+ // which is then subject to extension method lookup).
+ {
+ double t0 = fieldInOtherExtensionScope;
+ checkOtherExtensionValue(t0);
+ double t1 = getterInOtherExtensionScope;
+ checkOtherExtensionValue(t1);
+ setterInOtherExtensionScope = otherExtensionValue;
+ double t2 = methodInOtherExtensionScope();
+ checkOtherExtensionValue(t2);
+ }
+ }
+
+ void testIdentifiersOnThis() {
+ // Global symbols prefixed by `this` resolve to the version on the other
+ // extension
+ {
+ double t0 = this.fieldInGlobalScope;
+ checkOtherExtensionValue(t0);
+ double t1 = this.getterInGlobalScope;
+ checkOtherExtensionValue(t1);
+ this.setterInGlobalScope = otherExtensionValue;
+ double t2 = this.methodInGlobalScope();
+ checkOtherExtensionValue(t2);
+ }
+
+ // Instance members resolve to the instance methods and not the members
+ // of the other extension (when present)
+ {
+ String t0 = this.fieldInInstanceScope;
+ checkInstanceValue(t0);
+ String t1 = this.getterInInstanceScope;
+ checkInstanceValue(t0);
+ this.setterInInstanceScope = instanceValue;
+ String t2 = this.methodInInstanceScope();
+ checkInstanceValue(t0);
+ }
+
+ // Extension members resolve to the extension methods in the other
+ // extension.
+ {
+ double t0 = this.fieldInOtherExtensionScope;
+ checkOtherExtensionValue(t0);
+ double t1 = this.getterInOtherExtensionScope;
+ checkOtherExtensionValue(t1);
+ this.setterInOtherExtensionScope = otherExtensionValue;
+ double t2 = this.methodInOtherExtensionScope();
+ checkOtherExtensionValue(t2);
+ }
+ }
+
+ void testIdentifiersOnInstance() {
+ A self = this;
+
+ // Global symbols on an instance resolve to the version on the other
+ // extension
+ {
+ double t0 = self.fieldInGlobalScope;
+ checkOtherExtensionValue(t0);
+ double t1 = self.getterInGlobalScope;
+ checkOtherExtensionValue(t1);
+ self.setterInGlobalScope = otherExtensionValue;
+ double t2 = self.methodInGlobalScope();
+ checkOtherExtensionValue(t2);
+ }
+ // Instance members resolve to the instance methods and not the members
+ // of the other extension (when present)
+ {
+ String t0 = self.fieldInInstanceScope;
+ checkInstanceValue(t0);
+ String t1 = self.getterInInstanceScope;
+ checkInstanceValue(t1);
+ self.setterInInstanceScope = instanceValue;
+ String t2 = self.methodInInstanceScope();
+ checkInstanceValue(t2);
+ }
+
+ // Extension members resolve to the extension methods in the other
+ // extension.
+ {
+ double t0 = self.fieldInOtherExtensionScope;
+ checkOtherExtensionValue(t0);
+ double t1 = self.getterInOtherExtensionScope;
+ checkOtherExtensionValue(t1);
+ self.setterInOtherExtensionScope = otherExtensionValue;
+ double t2 = self.methodInOtherExtensionScope();
+ checkOtherExtensionValue(t2);
+ }
+ }
+
+ void instanceTest() {
+ MyExt(this).testNakedIdentifiers();
+ MyExt(this).testIdentifiersOnThis();
+ MyExt(this).testIdentifiersOnInstance();
+ }
+}
+
+class B extends A {
+ void testNakedIdentifiers() {
+ // Globals should resolve to the global name space, and not to the members
+ // of the other extension (when present)
+ {
+ int t0 = fieldInGlobalScope;
+ checkGlobalValue(t0);
+ int t1 = getterInGlobalScope;
+ checkGlobalValue(t1);
+ setterInGlobalScope = globalValue;
+ int t2 = methodInGlobalScope();
+ checkGlobalValue(t2);
+ }
+
+ // Instance members resolve to the instance methods and not the members
+ // of the other extension (when present)
+ {
+ String t0 = fieldInInstanceScope;
+ checkInstanceValue(t0);
+ String t1 = getterInInstanceScope;
+ checkInstanceValue(t0);
+ setterInInstanceScope = instanceValue;
+ String t2 = methodInInstanceScope();
+ checkInstanceValue(t0);
+ }
+
+ // Extension members resolve to the extension methods in the other
+ // extension (unresolved identifier "id" gets turned into "this.id",
+ // which is then subject to extension method lookup).
+ {
+ double t0 = fieldInOtherExtensionScope;
+ checkOtherExtensionValue(t0);
+ double t1 = getterInOtherExtensionScope;
+ checkOtherExtensionValue(t1);
+ setterInOtherExtensionScope = otherExtensionValue;
+ double t2 = methodInOtherExtensionScope();
+ checkOtherExtensionValue(t2);
+ }
+ }
+}
+
+void main() {
+ var a = new A();
+ a.instanceTest();
+ new B().testNakedIdentifiers();
+
+ // Check external resolution as well while we're here
+
+ // Global symbols on an instance resolve to the version on the other
+ // extension
+ {
+ double t0 = a.fieldInGlobalScope;
+ checkOtherExtensionValue(t0);
+ double t1 = a.getterInGlobalScope;
+ checkOtherExtensionValue(t1);
+ a.setterInGlobalScope = otherExtensionValue;
+ double t2 = a.methodInGlobalScope();
+ checkOtherExtensionValue(t2);
+ }
+
+ // Instance members resolve to the instance methods and not the members
+ // of the other extension (when present)
+ {
+ String t0 = a.fieldInInstanceScope;
+ checkInstanceValue(t0);
+ String t1 = a.getterInInstanceScope;
+ checkInstanceValue(t1);
+ a.setterInInstanceScope = instanceValue;
+ String t2 = a.methodInInstanceScope();
+ checkInstanceValue(t2);
+ }
+
+ // Extension members resolve to the extension methods in the other
+ // extension.
+ {
+ double t0 = a.fieldInOtherExtensionScope;
+ checkOtherExtensionValue(t0);
+ double t1 = a.getterInOtherExtensionScope;
+ checkOtherExtensionValue(t1);
+ a.setterInOtherExtensionScope = otherExtensionValue;
+ double t2 = a.methodInOtherExtensionScope();
+ checkOtherExtensionValue(t2);
+ }
+}
diff --git a/tests/language/extension_methods/static_extension_internal_resolution_2_test.dart b/tests/language/extension_methods/static_extension_internal_resolution_2_test.dart
new file mode 100644
index 0000000..861bb4b
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_internal_resolution_2_test.dart
@@ -0,0 +1,325 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+// Tests resolution of identifiers inside of extension methods
+
+// Test an extension MyExt with members whose names overlap with names from the
+// global, and instance scopes:
+// - a class A with only its own members
+// - an extension ExtraExt which has only its own members
+
+import "package:expect/expect.dart";
+
+/////////////////////////////////////////////////////////////////////////
+// Note: These imports may be deliberately unused. They bring certain
+// names into scope, in order to test that certain resolution choices are
+// made even in the presence of other symbols.
+/////////////////////////////////////////////////////////////////////////
+
+// Do Not Delete.
+// Bring global members into scope.
+import "helpers/global_scope.dart";
+
+// Do Not Delete.
+// Bring a class A with instance members into scope.
+import "helpers/class_no_shadow.dart";
+
+// Do Not Delete.
+// Bring an extension ExtraExt with no overlapping symbols into scope.
+import "helpers/extension_only.dart";
+
+const bool extensionValue = true;
+
+void checkExtensionValue(bool x) {
+ Expect.equals(x, extensionValue);
+}
+
+// An extension which defines all members
+extension MyExt on A {
+ bool get fieldInGlobalScope => true;
+ bool get getterInGlobalScope => true;
+ set setterInGlobalScope(bool x) {
+ Expect.equals(true, x);
+ }
+
+ bool methodInGlobalScope() => true;
+
+ bool get fieldInInstanceScope => true;
+ bool get getterInInstanceScope => true;
+ set setterInInstanceScope(bool x) {
+ Expect.equals(true, x);
+ }
+
+ bool methodInInstanceScope() => true;
+
+ bool get fieldInExtensionScope => true;
+ bool get getterInExtensionScope => true;
+ set setterInExtensionScope(bool x) {
+ Expect.equals(true, x);
+ }
+
+ bool methodInExtensionScope() => true;
+
+ void testNakedIdentifiers() {
+ // Globals should resolve to local extension versions
+ {
+ bool t0 = fieldInGlobalScope;
+ checkExtensionValue(t0);
+ bool t1 = getterInGlobalScope;
+ checkExtensionValue(t1);
+ setterInGlobalScope = extensionValue;
+ bool t2 = methodInGlobalScope();
+ checkExtensionValue(t2);
+ }
+
+ // Un-prefixed instance members resolve to the local extension versions
+ {
+ bool t0 = fieldInInstanceScope;
+ checkExtensionValue(t0);
+ bool t1 = getterInInstanceScope;
+ checkExtensionValue(t0);
+ setterInInstanceScope = extensionValue;
+ bool t2 = methodInInstanceScope();
+ checkExtensionValue(t0);
+ }
+
+ // Extension members resolve to the extension methods in this extension
+ {
+ bool t0 = fieldInExtensionScope;
+ checkExtensionValue(t0);
+ bool t1 = getterInExtensionScope;
+ checkExtensionValue(t1);
+ setterInExtensionScope = extensionValue;
+ bool t2 = methodInExtensionScope();
+ checkExtensionValue(t2);
+ }
+
+ // Extension members not on this extension resolve to the extension methods
+ // in the other extension (unresolved identifier "id" gets turned into
+ // "this.id", which is then subject to extension method lookup).
+ {
+ double t0 = fieldInOtherExtensionScope;
+ checkOtherExtensionValue(t0);
+ double t1 = getterInOtherExtensionScope;
+ checkOtherExtensionValue(t1);
+ setterInOtherExtensionScope = otherExtensionValue;
+ double t2 = methodInOtherExtensionScope();
+ checkOtherExtensionValue(t2);
+ }
+ }
+
+ void testIdentifiersOnThis() {
+ // Globals should resolve to local extension versions
+ {
+ bool t0 = this.fieldInGlobalScope;
+ checkExtensionValue(t0);
+ bool t1 = this.getterInGlobalScope;
+ checkExtensionValue(t1);
+ this.setterInGlobalScope = extensionValue;
+ bool t2 = this.methodInGlobalScope();
+ checkExtensionValue(t2);
+ }
+
+ // Instance members resolve to the instance methods and not the members
+ // of the extension
+ {
+ String t0 = this.fieldInInstanceScope;
+ checkInstanceValue(t0);
+ String t1 = this.getterInInstanceScope;
+ checkInstanceValue(t0);
+ this.setterInInstanceScope = instanceValue;
+ String t2 = this.methodInInstanceScope();
+ checkInstanceValue(t0);
+ }
+
+ // Extension members resolve to the extension methods on this extension
+ {
+ bool t0 = this.fieldInExtensionScope;
+ checkExtensionValue(t0);
+ bool t1 = this.getterInExtensionScope;
+ checkExtensionValue(t1);
+ this.setterInExtensionScope = extensionValue;
+ bool t2 = this.methodInExtensionScope();
+ checkExtensionValue(t2);
+ }
+
+ // Extension members not on this extension resolve to the extension methods
+ // in the other extension.
+ {
+ double t0 = this.fieldInOtherExtensionScope;
+ checkOtherExtensionValue(t0);
+ double t1 = this.getterInOtherExtensionScope;
+ checkOtherExtensionValue(t1);
+ this.setterInOtherExtensionScope = otherExtensionValue;
+ double t2 = this.methodInOtherExtensionScope();
+ checkOtherExtensionValue(t2);
+ }
+ }
+
+ void testIdentifiersOnInstance() {
+ A self = this;
+
+ // Globals should resolve to local extension versions
+ {
+ bool t0 = self.fieldInGlobalScope;
+ checkExtensionValue(t0);
+ bool t1 = self.getterInGlobalScope;
+ checkExtensionValue(t1);
+ self.setterInGlobalScope = extensionValue;
+ bool t2 = self.methodInGlobalScope();
+ checkExtensionValue(t2);
+ }
+
+ // Instance members resolve to the instance methods and not the members
+ // of the extension
+ {
+ String t0 = self.fieldInInstanceScope;
+ checkInstanceValue(t0);
+ String t1 = self.getterInInstanceScope;
+ checkInstanceValue(t0);
+ self.setterInInstanceScope = instanceValue;
+ String t2 = self.methodInInstanceScope();
+ checkInstanceValue(t0);
+ }
+
+ // Extension members resolve to the extension methods on this extension
+ {
+ bool t0 = self.fieldInExtensionScope;
+ checkExtensionValue(t0);
+ bool t1 = self.getterInExtensionScope;
+ checkExtensionValue(t1);
+ self.setterInExtensionScope = extensionValue;
+ bool t2 = self.methodInExtensionScope();
+ checkExtensionValue(t2);
+ }
+
+ // Extension members not on this extension resolve to the extension methods
+ // in the other extension.
+ {
+ double t0 = self.fieldInOtherExtensionScope;
+ checkOtherExtensionValue(t0);
+ double t1 = self.getterInOtherExtensionScope;
+ checkOtherExtensionValue(t1);
+ self.setterInOtherExtensionScope = otherExtensionValue;
+ double t2 = self.methodInOtherExtensionScope();
+ checkOtherExtensionValue(t2);
+ }
+ }
+
+ void instanceTest() {
+ MyExt(this).testNakedIdentifiers();
+ MyExt(this).testIdentifiersOnThis();
+ MyExt(this).testIdentifiersOnInstance();
+ }
+}
+
+class B extends A {
+ void testNakedIdentifiers() {
+ // Globals should resolve to the global name space, and not to the members
+ // of the other extension (when present)
+ {
+ int t0 = fieldInGlobalScope;
+ checkGlobalValue(t0);
+ int t1 = getterInGlobalScope;
+ checkGlobalValue(t1);
+ setterInGlobalScope = globalValue;
+ int t2 = methodInGlobalScope();
+ checkGlobalValue(t2);
+ }
+
+ // Instance members resolve to the instance methods and not the members
+ // of the other extension (when present)
+ {
+ String t0 = fieldInInstanceScope;
+ checkInstanceValue(t0);
+ String t1 = getterInInstanceScope;
+ checkInstanceValue(t0);
+ setterInInstanceScope = instanceValue;
+ String t2 = methodInInstanceScope();
+ checkInstanceValue(t0);
+ }
+
+ // Extension members defined only in this extension resolve correctly.
+ {
+ bool t0 = fieldInExtensionScope;
+ checkExtensionValue(t0);
+ bool t1 = getterInExtensionScope;
+ checkExtensionValue(t1);
+ setterInExtensionScope = extensionValue;
+ bool t2 = methodInExtensionScope();
+ checkExtensionValue(t2);
+ }
+
+ // Extension members defined in the external extension resolve correctly
+ // (an unresolved identifier "id" gets turned into "this.id",
+ // which is then subject to extension method lookup).
+ {
+ double t0 = fieldInOtherExtensionScope;
+ checkOtherExtensionValue(t0);
+ double t1 = getterInOtherExtensionScope;
+ checkOtherExtensionValue(t1);
+ setterInOtherExtensionScope = otherExtensionValue;
+ double t2 = methodInOtherExtensionScope();
+ checkOtherExtensionValue(t2);
+ }
+ }
+}
+
+void main() {
+ var a = new A();
+ a.instanceTest();
+ new B().testNakedIdentifiers();
+
+ // Check external resolution as well while we're here
+
+ // Global symbols on an instance resolve to the version on this
+ // extension
+ {
+ bool t0 = a.fieldInGlobalScope;
+ checkExtensionValue(t0);
+ bool t1 = a.getterInGlobalScope;
+ checkExtensionValue(t1);
+ a.setterInGlobalScope = extensionValue;
+ bool t2 = a.methodInGlobalScope();
+ checkExtensionValue(t2);
+ }
+
+ // Instance members resolve to the instance methods and not the members
+ // of the other extension (when present)
+ {
+ String t0 = a.fieldInInstanceScope;
+ checkInstanceValue(t0);
+ String t1 = a.getterInInstanceScope;
+ checkInstanceValue(t1);
+ a.setterInInstanceScope = instanceValue;
+ String t2 = a.methodInInstanceScope();
+ checkInstanceValue(t2);
+ }
+
+ // Extension members resolve to the extension methods in this
+ // extension.
+ {
+ bool t0 = a.fieldInExtensionScope;
+ checkExtensionValue(t0);
+ bool t1 = a.getterInExtensionScope;
+ checkExtensionValue(t1);
+ a.setterInExtensionScope = extensionValue;
+ bool t2 = a.methodInExtensionScope();
+ checkExtensionValue(t2);
+ }
+
+ // Extension members resolve to the extension methods in the other
+ // extension.
+ {
+ double t0 = a.fieldInOtherExtensionScope;
+ checkOtherExtensionValue(t0);
+ double t1 = a.getterInOtherExtensionScope;
+ checkOtherExtensionValue(t1);
+ a.setterInOtherExtensionScope = otherExtensionValue;
+ double t2 = a.methodInOtherExtensionScope();
+ checkOtherExtensionValue(t2);
+ }
+}
diff --git a/tests/language/extension_methods/static_extension_internal_resolution_3_error_test.dart b/tests/language/extension_methods/static_extension_internal_resolution_3_error_test.dart
new file mode 100644
index 0000000..b0409f9
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_internal_resolution_3_error_test.dart
@@ -0,0 +1,262 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+// Tests resolution of identifiers inside of extension methods
+
+// Test the error cases for an extension MyExt with member names
+// overlapping the global and instance scopes against:
+// - a class A with only its own members
+// - an extension ExtraExt which has global and instance members as well as
+// its own
+
+import "package:expect/expect.dart";
+
+/////////////////////////////////////////////////////////////////////////
+// Note: These imports may be deliberately unused. They bring certain
+// names into scope, in order to test that certain resolution choices are
+// made even in the presence of other symbols.
+/////////////////////////////////////////////////////////////////////////
+
+// Do Not Delete.
+// Bring global members into scope.
+import "helpers/global_scope.dart";
+
+// Do Not Delete.
+// Bring a class A with instance members into scope.
+import "helpers/class_no_shadow.dart";
+
+// Do Not Delete.
+// Bring an extension ExtraExt with members that overlap the global and instance
+// names into scope.
+import "helpers/extension_global_instance.dart";
+
+const bool extensionValue = true;
+
+void checkExtensionValue(bool x) {
+ Expect.equals(x, extensionValue);
+}
+
+// An extension which defines members of its own, as well members overlapping
+// the instance and global names.
+extension MyExt on A {
+ bool get fieldInGlobalScope => extensionValue;
+ bool get getterInGlobalScope => extensionValue;
+ set setterInGlobalScope(bool x) {
+ checkExtensionValue(x);
+ }
+
+ bool methodInGlobalScope() => extensionValue;
+
+ bool get fieldInInstanceScope => extensionValue;
+ bool get getterInInstanceScope => extensionValue;
+ set setterInInstanceScope(bool x) {
+ checkExtensionValue(x);
+ }
+
+ bool methodInInstanceScope() => extensionValue;
+
+ bool get fieldInExtensionScope => extensionValue;
+ bool get getterInExtensionScope => extensionValue;
+ set setterInExtensionScope(bool x) {
+ checkExtensionValue(x);
+ }
+
+ bool methodInExtensionScope() => extensionValue;
+
+ void testNakedIdentifiers() {
+ // Globals should resolve to local extension versions
+ {
+ // No errors: see static_extension_internal_resolution_3_test.dart
+ }
+
+ // Un-prefixed instance members resolve to the local extension versions
+ {
+ // No errors: see static_extension_internal_resolution_3_test.dart
+ }
+
+ // Extension members resolve to the extension methods in this extension
+ {
+ // No errors: see static_extension_internal_resolution_3_test.dart
+ }
+
+ // Extension members not on this extension resolve to the extension methods
+ // in the other extension (unresolved identifier "id" gets turned into
+ // "this.id", which is then subject to extension method lookup).
+ {
+ // No errors: see static_extension_internal_resolution_3_test.dart
+ }
+ }
+
+ void testIdentifiersOnThis() {
+ // Prefixed globals are ambiguous
+ {
+ bool t0 = this.fieldInGlobalScope;
+ // ^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The property 'fieldInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+ checkExtensionValue(t0);
+ bool t1 = this.getterInGlobalScope;
+ // ^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The property 'getterInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+ checkExtensionValue(t1);
+ this.setterInGlobalScope = extensionValue;
+ // ^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The property 'setterInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+ bool t2 = this.methodInGlobalScope();
+ // ^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The method 'methodInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+ checkExtensionValue(t2);
+ }
+
+ // Instance members resolve to the instance methods and not the members
+ // of either extension
+ {
+ // No errors: see static_extension_internal_resolution_3_test.dart
+ }
+
+ // Extension members resolve to the extension methods on this extension
+ {
+ // No errors: see static_extension_internal_resolution_3_test.dart
+ }
+
+ // Extension members not on this extension resolve to the extension methods
+ // in the other extension.
+ {
+ // No errors: see static_extension_internal_resolution_3_test.dart
+ }
+ }
+
+ void testIdentifiersOnInstance() {
+ A self = this;
+
+ // Prefixed globals are ambiguous
+ {
+ bool t0 = self.fieldInGlobalScope;
+ // ^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The property 'fieldInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+ checkExtensionValue(t0);
+ bool t1 = self.getterInGlobalScope;
+ // ^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The property 'getterInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+ checkExtensionValue(t1);
+ self.setterInGlobalScope = extensionValue;
+ // ^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The property 'setterInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+ bool t2 = self.methodInGlobalScope();
+ // ^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The method 'methodInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+ checkExtensionValue(t2);
+ }
+
+ // Instance members resolve to the instance methods and not the members
+ // of the extension
+ {
+ // No errors: see static_extension_internal_resolution_3_test.dart
+ }
+
+ // Extension members resolve to the extension methods on this extension
+ {
+ // No errors: see static_extension_internal_resolution_3_test.dart
+ }
+
+ // Extension members not on this extension resolve to the extension methods
+ // in the other extension.
+ {
+ // No errors: see static_extension_internal_resolution_3_test.dart
+ }
+ }
+
+ void instanceTest() {
+ MyExt(this).testNakedIdentifiers();
+ MyExt(this).testIdentifiersOnThis();
+ MyExt(this).testIdentifiersOnInstance();
+ }
+}
+
+class B extends A {
+ void testNakedIdentifiers() {
+ // Globals should resolve to the global name space, and not to the members
+ // of either extension
+ {
+ // No errors: see static_extension_internal_resolution_3_test.dart
+ }
+
+ // Instance members resolve to the instance methods and not the members
+ // of the other extension (when present)
+ {
+ // No errors: see static_extension_internal_resolution_3_test.dart
+ }
+
+ // Extension members resolve to the extension methods in the local
+ // extension.
+ {
+ // No errors: see static_extension_internal_resolution_3_test.dart
+ }
+
+ // Extension members resolve to the extension methods in the other
+ // extension (unresolved identifier "id" gets turned into "this.id",
+ // which is then subject to extension method lookup).
+ {
+ // No errors: see static_extension_internal_resolution_3_test.dart
+ }
+ }
+}
+
+void main() {
+ var a = new A();
+ a.instanceTest();
+ new B().testNakedIdentifiers();
+
+ // Check external resolution as well while we're here
+
+ // Global names come from both extensions and hence are ambiguous.
+ {
+ bool t0 = a.fieldInGlobalScope;
+ // ^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The property 'fieldInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+ checkExtensionValue(t0);
+ bool t1 = a.getterInGlobalScope;
+ // ^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The property 'getterInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+ checkExtensionValue(t1);
+ a.setterInGlobalScope = extensionValue;
+ //^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The property 'setterInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+ bool t2 = a.methodInGlobalScope();
+ // ^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The method 'methodInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+ checkExtensionValue(t2);
+ }
+
+ // Instance members resolve to the instance methods and not the members
+ // of the other extension (when present)
+ {
+ // No errors: see static_extension_internal_resolution_3_test.dart
+ }
+
+ // Extension members resolve to the extension methods in this
+ // extension.
+ {
+ // No errors: see static_extension_internal_resolution_3_test.dart
+ }
+
+ // Extension members resolve to the extension methods in the other
+ // extension.
+ {
+ // No errors: see static_extension_internal_resolution_3_test.dart
+ }
+}
diff --git a/tests/language/extension_methods/static_extension_internal_resolution_3_test.dart b/tests/language/extension_methods/static_extension_internal_resolution_3_test.dart
new file mode 100644
index 0000000..f6c57e9
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_internal_resolution_3_test.dart
@@ -0,0 +1,309 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+// Tests resolution of identifiers inside of extension methods
+
+// Test the non error cases for an extension MyExt with member names
+// overlapping the global and instance scopes against:
+// - a class A with only its own members
+// - an extension ExtraExt which has global and instance members as well as
+// its own
+
+import "package:expect/expect.dart";
+
+/////////////////////////////////////////////////////////////////////////
+// Note: These imports may be deliberately unused. They bring certain
+// names into scope, in order to test that certain resolution choices are
+// made even in the presence of other symbols.
+/////////////////////////////////////////////////////////////////////////
+
+// Do Not Delete.
+// Bring global members into scope.
+import "helpers/global_scope.dart";
+
+// Do Not Delete.
+// Bring a class A with instance members into scope.
+import "helpers/class_no_shadow.dart";
+
+// Do Not Delete.
+// Bring an extension ExtraExt with members that overlap the global and instance
+// names into scope.
+import "helpers/extension_global_instance.dart";
+
+const bool extensionValue = true;
+
+void checkExtensionValue(bool x) {
+ Expect.equals(x, extensionValue);
+}
+
+// An extension which defines members of its own, as well members overlapping
+// the instance and global names.
+extension MyExt on A {
+ bool get fieldInGlobalScope => extensionValue;
+ bool get getterInGlobalScope => extensionValue;
+ set setterInGlobalScope(bool x) {
+ checkExtensionValue(x);
+ }
+
+ bool methodInGlobalScope() => extensionValue;
+
+ bool get fieldInInstanceScope => extensionValue;
+ bool get getterInInstanceScope => extensionValue;
+ set setterInInstanceScope(bool x) {
+ checkExtensionValue(x);
+ }
+
+ bool methodInInstanceScope() => extensionValue;
+
+ bool get fieldInExtensionScope => extensionValue;
+ bool get getterInExtensionScope => extensionValue;
+ set setterInExtensionScope(bool x) {
+ checkExtensionValue(x);
+ }
+
+ bool methodInExtensionScope() => extensionValue;
+
+ void testNakedIdentifiers() {
+ // Globals should resolve to local extension versions
+ {
+ bool t0 = fieldInGlobalScope;
+ checkExtensionValue(t0);
+ bool t1 = getterInGlobalScope;
+ checkExtensionValue(t1);
+ setterInGlobalScope = extensionValue;
+ bool t2 = methodInGlobalScope();
+ checkExtensionValue(t2);
+ }
+
+ // Un-prefixed instance members resolve to the local extension versions
+ {
+ bool t0 = fieldInInstanceScope;
+ checkExtensionValue(t0);
+ bool t1 = getterInInstanceScope;
+ checkExtensionValue(t0);
+ setterInInstanceScope = extensionValue;
+ bool t2 = methodInInstanceScope();
+ checkExtensionValue(t0);
+ }
+
+ // Extension members resolve to the extension methods in this extension
+ {
+ bool t0 = fieldInExtensionScope;
+ checkExtensionValue(t0);
+ bool t1 = getterInExtensionScope;
+ checkExtensionValue(t1);
+ setterInExtensionScope = extensionValue;
+ bool t2 = methodInExtensionScope();
+ checkExtensionValue(t2);
+ }
+
+ // Extension members not on this extension resolve to the extension methods
+ // in the other extension (unresolved identifier "id" gets turned into
+ // "this.id", which is then subject to extension method lookup).
+ {
+ double t0 = fieldInOtherExtensionScope;
+ checkOtherExtensionValue(t0);
+ double t1 = getterInOtherExtensionScope;
+ checkOtherExtensionValue(t1);
+ setterInOtherExtensionScope = otherExtensionValue;
+ double t2 = methodInOtherExtensionScope();
+ checkOtherExtensionValue(t2);
+ }
+ }
+
+ void testIdentifiersOnThis() {
+ // Prefixed globals are ambiguous
+ {
+ // Error cases tested in static_extension_internal_resolution_3_error_test.dart
+ }
+
+ // Instance members resolve to the instance methods and not the members
+ // of either extension
+ {
+ String t0 = this.fieldInInstanceScope;
+ checkInstanceValue(t0);
+ String t1 = this.getterInInstanceScope;
+ checkInstanceValue(t0);
+ this.setterInInstanceScope = instanceValue;
+ String t2 = this.methodInInstanceScope();
+ checkInstanceValue(t0);
+ }
+
+ // Extension members resolve to the extension methods on this extension
+ {
+ bool t0 = this.fieldInExtensionScope;
+ checkExtensionValue(t0);
+ bool t1 = this.getterInExtensionScope;
+ checkExtensionValue(t1);
+ this.setterInExtensionScope = extensionValue;
+ bool t2 = this.methodInExtensionScope();
+ checkExtensionValue(t2);
+ }
+
+ // Extension members not on this extension resolve to the extension methods
+ // in the other extension.
+ {
+ double t0 = this.fieldInOtherExtensionScope;
+ checkOtherExtensionValue(t0);
+ double t1 = this.getterInOtherExtensionScope;
+ checkOtherExtensionValue(t1);
+ this.setterInOtherExtensionScope = otherExtensionValue;
+ double t2 = this.methodInOtherExtensionScope();
+ checkOtherExtensionValue(t2);
+ }
+ }
+
+ void testIdentifiersOnInstance() {
+ A self = this;
+
+ // Prefixed globals are ambiguous
+ {
+ // Error cases tested in static_extension_internal_resolution_3_error_test.dart
+ }
+
+ // Instance members resolve to the instance methods and not the members
+ // of the extension
+ {
+ String t0 = self.fieldInInstanceScope;
+ checkInstanceValue(t0);
+ String t1 = self.getterInInstanceScope;
+ checkInstanceValue(t0);
+ self.setterInInstanceScope = instanceValue;
+ String t2 = self.methodInInstanceScope();
+ checkInstanceValue(t0);
+ }
+
+ // Extension members resolve to the extension methods on this extension
+ {
+ bool t0 = self.fieldInExtensionScope;
+ checkExtensionValue(t0);
+ bool t1 = self.getterInExtensionScope;
+ checkExtensionValue(t1);
+ self.setterInExtensionScope = extensionValue;
+ bool t2 = self.methodInExtensionScope();
+ checkExtensionValue(t2);
+ }
+
+ // Extension members not on this extension resolve to the extension methods
+ // in the other extension.
+ {
+ double t0 = self.fieldInOtherExtensionScope;
+ checkOtherExtensionValue(t0);
+ double t1 = self.getterInOtherExtensionScope;
+ checkOtherExtensionValue(t1);
+ self.setterInOtherExtensionScope = otherExtensionValue;
+ double t2 = self.methodInOtherExtensionScope();
+ checkOtherExtensionValue(t2);
+ }
+ }
+
+ void instanceTest() {
+ MyExt(this).testNakedIdentifiers();
+ MyExt(this).testIdentifiersOnThis();
+ MyExt(this).testIdentifiersOnInstance();
+ }
+}
+
+class B extends A {
+ void testNakedIdentifiers() {
+ // Globals should resolve to the global name space, and not to the members
+ // of either extension
+ {
+ int t0 = fieldInGlobalScope;
+ checkGlobalValue(t0);
+ int t1 = getterInGlobalScope;
+ checkGlobalValue(t1);
+ setterInGlobalScope = globalValue;
+ int t2 = methodInGlobalScope();
+ checkGlobalValue(t2);
+ }
+
+ // Instance members resolve to the instance methods and not the members
+ // of the other extension (when present)
+ {
+ String t0 = fieldInInstanceScope;
+ checkInstanceValue(t0);
+ String t1 = getterInInstanceScope;
+ checkInstanceValue(t0);
+ setterInInstanceScope = instanceValue;
+ String t2 = methodInInstanceScope();
+ checkInstanceValue(t0);
+ }
+
+ // Extension members defined internally resolve correctly.
+ {
+ bool t0 = fieldInExtensionScope;
+ checkExtensionValue(t0);
+ bool t1 = getterInExtensionScope;
+ checkExtensionValue(t1);
+ setterInExtensionScope = extensionValue;
+ bool t2 = methodInExtensionScope();
+ checkExtensionValue(t2);
+ }
+
+ // Extension members defined elsewhere resolve correctly
+ // (an unresolved identifier "id" gets turned into "this.id",
+ // which is then subject to extension method lookup).
+ {
+ double t0 = fieldInOtherExtensionScope;
+ checkOtherExtensionValue(t0);
+ double t1 = getterInOtherExtensionScope;
+ checkOtherExtensionValue(t1);
+ setterInOtherExtensionScope = otherExtensionValue;
+ double t2 = methodInOtherExtensionScope();
+ checkOtherExtensionValue(t2);
+ }
+ }
+}
+
+void main() {
+ var a = new A();
+ a.instanceTest();
+ new B().testNakedIdentifiers();
+
+ // Check external resolution as well while we're here
+
+ // Global names come from both extensions and hence are ambiguous.
+ {
+ // Error cases tested in static_extension_internal_resolution_3_error_test.dart
+ }
+
+ // Instance members resolve to the instance methods and not the members
+ // of the other extension (when present)
+ {
+ String t0 = a.fieldInInstanceScope;
+ checkInstanceValue(t0);
+ String t1 = a.getterInInstanceScope;
+ checkInstanceValue(t1);
+ a.setterInInstanceScope = instanceValue;
+ String t2 = a.methodInInstanceScope();
+ checkInstanceValue(t2);
+ }
+
+ // Extension members resolve to the extension methods in this
+ // extension.
+ {
+ bool t0 = a.fieldInExtensionScope;
+ checkExtensionValue(t0);
+ bool t1 = a.getterInExtensionScope;
+ checkExtensionValue(t1);
+ a.setterInExtensionScope = extensionValue;
+ bool t2 = a.methodInExtensionScope();
+ checkExtensionValue(t2);
+ }
+
+ // Extension members resolve to the extension methods in the other
+ // extension.
+ {
+ double t0 = a.fieldInOtherExtensionScope;
+ checkOtherExtensionValue(t0);
+ double t1 = a.getterInOtherExtensionScope;
+ checkOtherExtensionValue(t1);
+ a.setterInOtherExtensionScope = otherExtensionValue;
+ double t2 = a.methodInOtherExtensionScope();
+ checkOtherExtensionValue(t2);
+ }
+}
diff --git a/tests/language/extension_methods/static_extension_internal_resolution_4_error_test.dart b/tests/language/extension_methods/static_extension_internal_resolution_4_error_test.dart
new file mode 100644
index 0000000..6cd8d4b
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_internal_resolution_4_error_test.dart
@@ -0,0 +1,338 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+// Tests resolution of identifiers inside of extension methods
+
+// Test the error cases for an extension MyExt with member names
+// overlapping the global and instance scopes against:
+// - a class A with only its own members
+// - an extension ExtraExt which has members overlapping the global names,
+// the instance names from A, and the extension names from MyExt, as well as
+// its own names.
+
+import "package:expect/expect.dart";
+
+/////////////////////////////////////////////////////////////////////////
+// Note: These imports may be deliberately unused. They bring certain
+// names into scope, in order to test that certain resolution choices are
+// made even in the presence of other symbols.
+/////////////////////////////////////////////////////////////////////////
+
+// Do Not Delete.
+// Bring global members into scope.
+import "helpers/global_scope.dart";
+
+// Do Not Delete.
+// Bring a class A with instance members into scope.
+import "helpers/class_no_shadow.dart";
+
+// Do Not Delete.
+// Bring an extension ExtraExt with symbols that overlap the global, instance,
+// and extension names into scope.
+import "helpers/extension_all.dart";
+
+const bool extensionValue = true;
+
+void checkExtensionValue(bool x) {
+ Expect.equals(x, extensionValue);
+}
+
+// An extension which defines its own members
+extension MyExt on A {
+ bool get fieldInGlobalScope => extensionValue;
+ bool get getterInGlobalScope => extensionValue;
+ set setterInGlobalScope(bool x) {
+ checkExtensionValue(x);
+ }
+
+ bool methodInGlobalScope() => extensionValue;
+
+ bool get fieldInInstanceScope => extensionValue;
+ bool get getterInInstanceScope => extensionValue;
+ set setterInInstanceScope(bool x) {
+ checkExtensionValue(x);
+ }
+
+ bool methodInInstanceScope() => extensionValue;
+
+ bool get fieldInExtensionScope => extensionValue;
+ bool get getterInExtensionScope => extensionValue;
+ set setterInExtensionScope(bool x) {
+ checkExtensionValue(x);
+ }
+
+ bool methodInExtensionScope() => extensionValue;
+
+ void testNakedIdentifiers() {
+ // Globals should resolve to local extension versions
+ {
+ // No errors: see static_extension_internal_resolution_4_test.dart
+ }
+
+ // Un-prefixed instance members resolve to the local extension versions
+ {
+ // No errors: see static_extension_internal_resolution_4_test.dart
+ }
+
+ // Extension members resolve to the extension methods in this extension
+ {
+ // No errors: see static_extension_internal_resolution_4_test.dart
+ }
+
+ // Extension members not on this extension resolve to the extension methods
+ // in the other extension (unresolved identifier "id" gets turned into
+ // "this.id", which is then subject to extension method lookup).
+ {
+ // No errors: see static_extension_internal_resolution_4_test.dart
+ }
+ }
+
+ void testIdentifiersOnThis() {
+ // Prefixed globals are ambiguous
+ {
+ bool t0 = this.fieldInGlobalScope;
+ // ^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The property 'fieldInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+ checkExtensionValue(t0);
+ bool t1 = this.getterInGlobalScope;
+ // ^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The property 'getterInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+ checkExtensionValue(t1);
+ this.setterInGlobalScope = extensionValue;
+ // ^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The property 'setterInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+ bool t2 = this.methodInGlobalScope();
+ // ^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The method 'methodInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+ checkExtensionValue(t2);
+ }
+
+ // Instance members resolve to the instance methods and not the members
+ // of either extension
+ {
+ // No errors: see static_extension_internal_resolution_4_test.dart
+ }
+
+ // Extension members are ambigious.
+ {
+ bool t0 = this.fieldInExtensionScope;
+ // ^^^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The property 'fieldInExtensionScope' is defined in multiple extensions for 'A' and neither is more specific.
+ checkExtensionValue(t0);
+ bool t1 = this.getterInExtensionScope;
+ // ^^^^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The property 'getterInExtensionScope' is defined in multiple extensions for 'A' and neither is more specific.
+ checkExtensionValue(t1);
+ this.setterInExtensionScope = extensionValue;
+ // ^^^^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The property 'setterInExtensionScope' is defined in multiple extensions for 'A' and neither is more specific.
+ bool t2 = this.methodInExtensionScope();
+ // ^^^^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The method 'methodInExtensionScope' is defined in multiple extensions for 'A' and neither is more specific.
+ checkExtensionValue(t2);
+ }
+
+ // Extension members not on this extension resolve to the extension methods
+ // in the other extension.
+ {
+ // No errors: see static_extension_internal_resolution_4_test.dart
+ }
+ }
+
+ void testIdentifiersOnInstance() {
+ A self = this;
+
+ // Prefixed globals are ambiguous
+ {
+ bool t0 = self.fieldInGlobalScope;
+ // ^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The property 'fieldInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+ checkExtensionValue(t0);
+ bool t1 = self.getterInGlobalScope;
+ // ^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The property 'getterInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+ checkExtensionValue(t1);
+ self.setterInGlobalScope = extensionValue;
+ // ^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The property 'setterInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+ bool t2 = self.methodInGlobalScope();
+ // ^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The method 'methodInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+ checkExtensionValue(t2);
+ }
+
+ // Instance members resolve to the instance methods and not the members
+ // of the extension
+ {
+ // No errors: see static_extension_internal_resolution_4_test.dart
+ }
+
+ // Extension members are ambigious.
+ {
+ bool t0 = self.fieldInExtensionScope;
+ // ^^^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The property 'fieldInExtensionScope' is defined in multiple extensions for 'A' and neither is more specific.
+ checkExtensionValue(t0);
+ bool t1 = self.getterInExtensionScope;
+ // ^^^^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The property 'getterInExtensionScope' is defined in multiple extensions for 'A' and neither is more specific.
+ checkExtensionValue(t1);
+ self.setterInExtensionScope = extensionValue;
+ // ^^^^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The property 'setterInExtensionScope' is defined in multiple extensions for 'A' and neither is more specific.
+ bool t2 = self.methodInExtensionScope();
+ // ^^^^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The method 'methodInExtensionScope' is defined in multiple extensions for 'A' and neither is more specific.
+ checkExtensionValue(t2);
+ }
+
+ // Extension members not on this extension resolve to the extension methods
+ // in the other extension.
+ {
+ // No errors: see static_extension_internal_resolution_4_test.dart
+ }
+ }
+
+ void instanceTest() {
+ MyExt(this).testNakedIdentifiers();
+ MyExt(this).testIdentifiersOnThis();
+ MyExt(this).testIdentifiersOnInstance();
+ }
+}
+
+class B extends A {
+ void testNakedIdentifiers() {
+ // Globals should resolve to the global name space, and not to the members
+ // of either extension
+ {
+ // No errors: see static_extension_internal_resolution_4_test.dart
+ }
+
+ // Instance members resolve to the instance methods and not the members
+ // of the other extension (when present)
+ {
+ // No errors: see static_extension_internal_resolution_4_test.dart
+ }
+
+ // Extension members are ambiguous
+ {
+ bool t0 = fieldInExtensionScope;
+ // ^^^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The property 'fieldInExtensionScope' is defined in multiple extensions for 'B' and neither is more specific.
+ // ^^^^^^^^^^^^^^^^^^^^^
+ // [analyzer] STATIC_WARNING.UNDEFINED_IDENTIFIER
+ checkExtensionValue(t0);
+ bool t1 = getterInExtensionScope;
+ // ^^^^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The property 'getterInExtensionScope' is defined in multiple extensions for 'B' and neither is more specific.
+ // ^^^^^^^^^^^^^^^^^^^^^^
+ // [analyzer] STATIC_WARNING.UNDEFINED_IDENTIFIER
+ checkExtensionValue(t1);
+ setterInExtensionScope = extensionValue;
+// ^^^^^^^^^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+// [cfe] The property 'setterInExtensionScope' is defined in multiple extensions for 'B' and neither is more specific.
+// ^^^^^^^^^^^^^^^^^^^^^^
+// [analyzer] STATIC_WARNING.UNDEFINED_IDENTIFIER
+ bool t2 = methodInExtensionScope();
+ // ^^^^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The method 'methodInExtensionScope' is defined in multiple extensions for 'B' and neither is more specific.
+ checkExtensionValue(t2);
+ }
+
+ // Extension members resolve to the extension methods in the other
+ // extension (unresolved identifier "id" gets turned into "this.id",
+ // which is then subject to extension method lookup).
+ {
+ // No errors: see static_extension_internal_resolution_4_test.dart
+ }
+ }
+}
+
+void main() {
+ var a = new A();
+ a.instanceTest();
+ new B().testNakedIdentifiers();
+
+ // Check external resolution as well while we're here
+
+ // Global names come from both extensions and hence are ambiguous.
+ {
+ bool t0 = a.fieldInGlobalScope;
+ // ^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The property 'fieldInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+ checkExtensionValue(t0);
+ bool t1 = a.getterInGlobalScope;
+ // ^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The property 'getterInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+ checkExtensionValue(t1);
+ a.setterInGlobalScope = extensionValue;
+ //^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The property 'setterInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+ bool t2 = a.methodInGlobalScope();
+ // ^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The method 'methodInGlobalScope' is defined in multiple extensions for 'A' and neither is more specific.
+ checkExtensionValue(t2);
+ }
+
+ // Instance members resolve to the instance methods and not the members
+ // of the other extension (when present)
+ {
+ // No errors: see static_extension_internal_resolution_4_test.dart
+ }
+
+ // Extension members are ambiguous
+ {
+ bool t0 = a.fieldInExtensionScope;
+ // ^^^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The property 'fieldInExtensionScope' is defined in multiple extensions for 'A' and neither is more specific.
+ checkExtensionValue(t0);
+ bool t1 = a.getterInExtensionScope;
+ // ^^^^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The property 'getterInExtensionScope' is defined in multiple extensions for 'A' and neither is more specific.
+ checkExtensionValue(t1);
+ a.setterInExtensionScope = extensionValue;
+ //^^^^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The property 'setterInExtensionScope' is defined in multiple extensions for 'A' and neither is more specific.
+ bool t2 = a.methodInExtensionScope();
+ // ^^^^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The method 'methodInExtensionScope' is defined in multiple extensions for 'A' and neither is more specific.
+ checkExtensionValue(t2);
+ }
+
+ // Extension members resolve to the extension methods in the other
+ // extension.
+ {
+ // No errors: see static_extension_internal_resolution_4_test.dart
+ }
+}
diff --git a/tests/language/extension_methods/static_extension_internal_resolution_4_test.dart b/tests/language/extension_methods/static_extension_internal_resolution_4_test.dart
new file mode 100644
index 0000000..93955cb
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_internal_resolution_4_test.dart
@@ -0,0 +1,284 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+// Tests resolution of identifiers inside of extension methods
+
+// Test the non error cases for an extension MyExt with member names
+// overlapping the global and instance scopes against:
+// - a class A with only its own members
+// - an extension ExtraExt which has members overlapping the global names,
+// the instance names from A, and the extension names from MyExt, as well as
+// its own names.
+
+import "package:expect/expect.dart";
+
+/////////////////////////////////////////////////////////////////////////
+// Note: These imports may be deliberately unused. They bring certain
+// names into scope, in order to test that certain resolution choices are
+// made even in the presence of other symbols.
+/////////////////////////////////////////////////////////////////////////
+
+// Do Not Delete.
+// Bring global members into scope.
+import "helpers/global_scope.dart";
+
+// Do Not Delete.
+// Bring a class A with instance members into scope.
+import "helpers/class_no_shadow.dart";
+
+// Do Not Delete.
+// Bring an extension ExtraExt with symbols that overlap the global, instance,
+// and extension names into scope.
+import "helpers/extension_all.dart";
+
+const bool extensionValue = true;
+
+void checkExtensionValue(bool x) {
+ Expect.equals(x, extensionValue);
+}
+
+// An extension which defines its own members
+extension MyExt on A {
+ bool get fieldInGlobalScope => extensionValue;
+ bool get getterInGlobalScope => extensionValue;
+ set setterInGlobalScope(bool x) {
+ checkExtensionValue(x);
+ }
+
+ bool methodInGlobalScope() => extensionValue;
+
+ bool get fieldInInstanceScope => extensionValue;
+ bool get getterInInstanceScope => extensionValue;
+ set setterInInstanceScope(bool x) {
+ checkExtensionValue(x);
+ }
+
+ bool methodInInstanceScope() => extensionValue;
+
+ bool get fieldInExtensionScope => extensionValue;
+ bool get getterInExtensionScope => extensionValue;
+ set setterInExtensionScope(bool x) {
+ checkExtensionValue(x);
+ }
+
+ bool methodInExtensionScope() => extensionValue;
+
+ void testNakedIdentifiers() {
+ // Globals should resolve to local extension versions
+ {
+ bool t0 = fieldInGlobalScope;
+ checkExtensionValue(t0);
+ bool t1 = getterInGlobalScope;
+ checkExtensionValue(t1);
+ setterInGlobalScope = extensionValue;
+ bool t2 = methodInGlobalScope();
+ checkExtensionValue(t2);
+ }
+
+ // Un-prefixed instance members resolve to the local extension versions
+ {
+ bool t0 = fieldInInstanceScope;
+ checkExtensionValue(t0);
+ bool t1 = getterInInstanceScope;
+ checkExtensionValue(t0);
+ setterInInstanceScope = extensionValue;
+ bool t2 = methodInInstanceScope();
+ checkExtensionValue(t0);
+ }
+
+ // Extension members resolve to the extension methods in this extension
+ {
+ bool t0 = fieldInExtensionScope;
+ checkExtensionValue(t0);
+ bool t1 = getterInExtensionScope;
+ checkExtensionValue(t1);
+ setterInExtensionScope = extensionValue;
+ bool t2 = methodInExtensionScope();
+ checkExtensionValue(t2);
+ }
+
+ // Extension members not on this extension resolve to the extension methods
+ // in the other extension (unresolved identifier "id" gets turned into
+ // "this.id", which is then subject to extension method lookup).
+ {
+ double t0 = fieldInOtherExtensionScope;
+ checkOtherExtensionValue(t0);
+ double t1 = getterInOtherExtensionScope;
+ checkOtherExtensionValue(t1);
+ setterInOtherExtensionScope = otherExtensionValue;
+ double t2 = methodInOtherExtensionScope();
+ checkOtherExtensionValue(t2);
+ }
+ }
+
+ void testIdentifiersOnThis() {
+ // Prefixed globals are ambiguous
+ {
+ // Error cases tested in static_extension_internal_resolution_4_error_test.dart
+ }
+
+ // Instance members resolve to the instance methods and not the members
+ // of either extension
+ {
+ String t0 = this.fieldInInstanceScope;
+ checkInstanceValue(t0);
+ String t1 = this.getterInInstanceScope;
+ checkInstanceValue(t0);
+ this.setterInInstanceScope = instanceValue;
+ String t2 = this.methodInInstanceScope();
+ checkInstanceValue(t0);
+ }
+
+ // Extension members are ambigious.
+ {
+ // Error cases tested in static_extension_internal_resolution_4_error_test.dart
+ }
+
+ // Extension members not on this extension resolve to the extension methods
+ // in the other extension.
+ {
+ double t0 = this.fieldInOtherExtensionScope;
+ checkOtherExtensionValue(t0);
+ double t1 = this.getterInOtherExtensionScope;
+ checkOtherExtensionValue(t1);
+ this.setterInOtherExtensionScope = otherExtensionValue;
+ double t2 = this.methodInOtherExtensionScope();
+ checkOtherExtensionValue(t2);
+ }
+ }
+
+ void testIdentifiersOnInstance() {
+ A self = this;
+
+ // Prefixed globals are ambiguous
+ {
+ // Error cases tested in static_extension_internal_resolution_4_error_test.dart
+ }
+
+ // Instance members resolve to the instance methods and not the members
+ // of the extension
+ {
+ String t0 = self.fieldInInstanceScope;
+ checkInstanceValue(t0);
+ String t1 = self.getterInInstanceScope;
+ checkInstanceValue(t0);
+ self.setterInInstanceScope = instanceValue;
+ String t2 = self.methodInInstanceScope();
+ checkInstanceValue(t0);
+ }
+
+ // Extension members are ambigious.
+ {
+ // Error cases tested in static_extension_internal_resolution_4_error_test.dart
+ }
+
+ // Extension members not on this extension resolve to the extension methods
+ // in the other extension.
+ {
+ double t0 = self.fieldInOtherExtensionScope;
+ checkOtherExtensionValue(t0);
+ double t1 = self.getterInOtherExtensionScope;
+ checkOtherExtensionValue(t1);
+ self.setterInOtherExtensionScope = otherExtensionValue;
+ double t2 = self.methodInOtherExtensionScope();
+ checkOtherExtensionValue(t2);
+ }
+ }
+
+ void instanceTest() {
+ MyExt(this).testNakedIdentifiers();
+ MyExt(this).testIdentifiersOnThis();
+ MyExt(this).testIdentifiersOnInstance();
+ }
+}
+
+class B extends A {
+ void testNakedIdentifiers() {
+ // Globals should resolve to the global name space, and not to the members
+ // of either extension
+ {
+ int t0 = fieldInGlobalScope;
+ checkGlobalValue(t0);
+ int t1 = getterInGlobalScope;
+ checkGlobalValue(t1);
+ setterInGlobalScope = globalValue;
+ int t2 = methodInGlobalScope();
+ checkGlobalValue(t2);
+ }
+
+ // Instance members resolve to the instance methods and not the members
+ // of the other extension (when present)
+ {
+ String t0 = fieldInInstanceScope;
+ checkInstanceValue(t0);
+ String t1 = getterInInstanceScope;
+ checkInstanceValue(t0);
+ setterInInstanceScope = instanceValue;
+ String t2 = methodInInstanceScope();
+ checkInstanceValue(t0);
+ }
+
+ // Extension members are ambigious.
+ {
+ // Error cases tested in static_extension_internal_resolution_4_error_test.dart
+ }
+
+ // Extension members resolve to the extension methods in the other
+ // extension (unresolved identifier "id" gets turned into "this.id",
+ // which is then subject to extension method lookup).
+ {
+ double t0 = fieldInOtherExtensionScope;
+ checkOtherExtensionValue(t0);
+ double t1 = getterInOtherExtensionScope;
+ checkOtherExtensionValue(t1);
+ setterInOtherExtensionScope = otherExtensionValue;
+ double t2 = methodInOtherExtensionScope();
+ checkOtherExtensionValue(t2);
+ }
+ }
+}
+
+void main() {
+ var a = new A();
+ a.instanceTest();
+ new B().testNakedIdentifiers();
+
+ // Check external resolution as well while we're here
+
+ // Global names come from both extensions and hence are ambiguous.
+ {
+ // Error cases tested in static_extension_internal_resolution_4_error_test.dart
+ }
+
+ // Instance members resolve to the instance methods and not the members
+ // of the other extension (when present)
+ {
+ String t0 = a.fieldInInstanceScope;
+ checkInstanceValue(t0);
+ String t1 = a.getterInInstanceScope;
+ checkInstanceValue(t1);
+ a.setterInInstanceScope = instanceValue;
+ String t2 = a.methodInInstanceScope();
+ checkInstanceValue(t2);
+ }
+
+ // Extension members are ambigious.
+ {
+ // Error cases tested in static_extension_internal_resolution_4_error_test.dart
+ }
+
+ // Extension members resolve to the extension methods in the other
+ // extension.
+ {
+ double t0 = a.fieldInOtherExtensionScope;
+ checkOtherExtensionValue(t0);
+ double t1 = a.getterInOtherExtensionScope;
+ checkOtherExtensionValue(t1);
+ a.setterInOtherExtensionScope = otherExtensionValue;
+ double t2 = a.methodInOtherExtensionScope();
+ checkOtherExtensionValue(t2);
+ }
+}
diff --git a/tests/language/extension_methods/static_extension_internal_resolution_5_test.dart b/tests/language/extension_methods/static_extension_internal_resolution_5_test.dart
new file mode 100644
index 0000000..0334769
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_internal_resolution_5_test.dart
@@ -0,0 +1,163 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+// Tests resolution of identifiers inside of extension methods
+
+// Test the non error cases for an extension MyExt with member names
+// overlapping the instance scopes against:
+// - a class AGlobal which overlaps the names from the global scope as well
+// as providing its own members
+
+import "package:expect/expect.dart";
+
+/////////////////////////////////////////////////////////////////////////
+// Note: These imports may be deliberately unused. They bring certain
+// names into scope, in order to test that certain resolution choices are
+// made even in the presence of other symbols.
+/////////////////////////////////////////////////////////////////////////
+
+// Do Not Delete.
+// Bring global members into scope.
+import "helpers/global_scope.dart";
+
+// Do Not Delete.
+// Bring a class AGlobal with instance members and global members into scope.
+import "helpers/class_shadow.dart";
+import "helpers/class_no_shadow.dart";
+
+const bool extensionValue = true;
+
+void checkExtensionValue(bool x) {
+ Expect.equals(x, extensionValue);
+}
+
+// Put the extension members in the global scope
+int fieldInExtensionScope = globalValue;
+int get getterInExtensionScope => globalValue;
+set setterInExtensionScope(int x) {
+ checkGlobalValue(x);
+}
+
+int methodInExtensionScope() => globalValue;
+
+// Put the superclass members in the global scope
+int fieldInInstanceScope = globalValue;
+int get getterInInstanceScope => globalValue;
+set setterInInstanceScope(int x) {
+ checkGlobalValue(x);
+}
+
+int methodInInstanceScope() => globalValue;
+
+// An extension which defines only its own members
+extension MyExt on AGlobal {
+ bool get fieldInExtensionScope => extensionValue;
+ bool get getterInExtensionScope => extensionValue;
+ set setterInExtensionScope(bool x) {
+ checkExtensionValue(x);
+ }
+
+ bool methodInExtensionScope() => extensionValue;
+
+ bool get fieldInInstanceScope => extensionValue;
+ bool get getterInInstanceScope => extensionValue;
+ set setterInInstanceScope(bool x) {
+ checkExtensionValue(x);
+ }
+
+ bool methodInInstanceScope() => extensionValue;
+
+ void testNakedIdentifiers() {
+ // Members that are in the global namespace and the instance namespace
+ // resolve to the global namespace.
+ {
+ int t0 = fieldInGlobalScope;
+ checkGlobalValue(t0);
+ int t1 = getterInGlobalScope;
+ checkGlobalValue(t1);
+ setterInGlobalScope = globalValue;
+ int t2 = methodInGlobalScope();
+ checkGlobalValue(t2);
+ }
+
+ // Members that are in the global namespace and the local namespace resolve
+ // to the local namespace.
+ {
+ bool t0 = fieldInExtensionScope;
+ checkExtensionValue(t0);
+ bool t1 = getterInExtensionScope;
+ checkExtensionValue(t1);
+ setterInExtensionScope = extensionValue;
+ bool t2 = methodInExtensionScope();
+ checkExtensionValue(t2);
+ }
+
+ // Members that are in the global namespace and the instance and the local
+ // namespace resolve to the local namespace.
+ {
+ bool t0 = fieldInInstanceScope;
+ checkExtensionValue(t0);
+ bool t1 = getterInInstanceScope;
+ checkExtensionValue(t1);
+ setterInInstanceScope = extensionValue;
+ bool t2 = methodInInstanceScope();
+ checkExtensionValue(t2);
+ }
+ }
+
+ void instanceTest() {
+ MyExt(this).testNakedIdentifiers();
+ }
+}
+
+class B extends AGlobal {
+ void testNakedIdentifiers() {
+ // Members that are in the global namespace and the superclass namespace
+ // should resolve to the global name space, and not to the members of the
+ // superclass.
+ {
+ int t0 = fieldInGlobalScope;
+ checkGlobalValue(t0);
+ int t1 = getterInGlobalScope;
+ checkGlobalValue(t1);
+ setterInGlobalScope = globalValue;
+ int t2 = methodInGlobalScope();
+ checkGlobalValue(t2);
+ }
+
+ // Members that are in the global namespace and the extension namespace
+ // should resolve to the global name space, and not to the members of the
+ // extension.
+ {
+ int t0 = fieldInExtensionScope;
+ checkGlobalValue(t0);
+ int t1 = getterInExtensionScope;
+ checkGlobalValue(t1);
+ setterInExtensionScope = globalValue;
+ int t2 = methodInExtensionScope();
+ checkGlobalValue(t2);
+ }
+
+ // Members that are in the global namespace, and the superclass namespace,
+ // and the extension namespace, should resolve to the global name space, and
+ // not to the members of the extension nor the members of the superclass.
+ {
+ int t0 = fieldInInstanceScope;
+ checkGlobalValue(t0);
+ int t1 = getterInInstanceScope;
+ checkGlobalValue(t1);
+ setterInInstanceScope = globalValue;
+ int t2 = methodInInstanceScope();
+ checkGlobalValue(t2);
+ }
+ }
+}
+
+void main() {
+ var a = new AGlobal();
+ a.instanceTest();
+ new B().testNakedIdentifiers();
+}
diff --git a/tests/language/extension_methods/static_extension_internal_resolution_6_error_test.dart b/tests/language/extension_methods/static_extension_internal_resolution_6_error_test.dart
new file mode 100644
index 0000000..258feaa
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_internal_resolution_6_error_test.dart
@@ -0,0 +1,124 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+// Tests resolution of identifiers inside of extension methods
+
+// Test various static error corner cases around internal resolution.
+
+import "package:expect/expect.dart";
+
+/////////////////////////////////////////////////////////////////////////
+// Note: These imports may be deliberately unused. They bring certain
+// names into scope, in order to test that certain resolution choices are
+// made even in the presence of other symbols.
+/////////////////////////////////////////////////////////////////////////
+
+// Do Not Delete.
+// Bring global members into scope.
+import "helpers/global_scope.dart";
+
+// Do Not Delete.
+// Bring a class AGlobal with instance members and global members into scope.
+import "helpers/class_shadow.dart";
+
+extension GenericExtension<T> on T {
+ T get self => this;
+ // Check that capture is avoided when expanding out
+ // self references.
+ void shadowTypeParam<T>(T x) {
+ T y = self;
+ // ^^^^
+ // [analyzer] STATIC_TYPE_WARNING.INVALID_ASSIGNMENT
+ // [cfe] A value of type '#T' can't be assigned to a variable of type 'T'.
+ }
+
+ void castToShadowedTypeParam<T>() {
+ dynamic s = self;
+ (s as T);
+ }
+
+ List<T> mkList() => <T>[];
+ void castToShadowedTypeList<T>() {
+ (mkList() as List<T>);
+ }
+}
+
+const bool extensionValue = true;
+
+void checkExtensionValue(bool x) {
+ Expect.equals(x, extensionValue);
+}
+
+extension StaticExt on AGlobal {
+ // Valid to overlap static names with the target type symbols
+ static bool get fieldInInstanceScope => extensionValue;
+ // ^^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+ static bool get getterInInstanceScope => extensionValue;
+ // ^^^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+ static set setterInInstanceScope(bool x) {
+ // ^^^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+ checkExtensionValue(x);
+ }
+
+ static bool methodInInstanceScope() => extensionValue;
+ // ^^^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE
+
+ // Add the global symbols
+ static bool get fieldInGlobalScope => extensionValue;
+ static bool get getterInGlobalScope => extensionValue;
+ static set setterInGlobalScope(bool x) {
+ checkExtensionValue(x);
+ }
+
+ static bool methodInGlobalScope() => extensionValue;
+
+ // Invalid to overlap the static and extension scopes
+ bool get fieldInInstanceScope => extensionValue;
+ // ^
+ // [cfe] 'fieldInInstanceScope' is already declared in this scope.
+ bool get getterInInstanceScope => extensionValue;
+ // ^
+ // [cfe] 'getterInInstanceScope' is already declared in this scope.
+ set setterInInstanceScope(bool x) {
+ //^
+ // [cfe] 'setterInInstanceScope' is already declared in this scope.
+ checkExtensionValue(x);
+ }
+
+ bool methodInInstanceScope() => extensionValue;
+ // ^
+ // [cfe] 'methodInInstanceScope' is already declared in this scope.
+
+ void testNakedIdentifiers() {
+ // Symbols in the global scope and the local static scope resolve to
+ // the local static scope.
+ {
+ // No errors: see static_extension_internal_resolution_6_test.dart
+ }
+
+ // Symbols in the global scope, the instance scope, and the local static scope
+ // resolve to the local static scope.
+ {
+ // No errors: see static_extension_internal_resolution_6_test.dart
+ }
+ }
+
+ void instanceTest() {
+ StaticExt(this).testNakedIdentifiers();
+ }
+}
+
+void main() {
+ var a = new AGlobal();
+ a.instanceTest();
+
+ Expect.throwsTypeError(() => 3.castToShadowedTypeParam<String>());
+ Expect.throwsTypeError(() => 3.castToShadowedTypeList<String>());
+}
diff --git a/tests/language/extension_methods/static_extension_internal_resolution_6_test.dart b/tests/language/extension_methods/static_extension_internal_resolution_6_test.dart
new file mode 100644
index 0000000..f8dd416
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_internal_resolution_6_test.dart
@@ -0,0 +1,101 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+// Tests resolution of identifiers inside of extension methods
+
+// Test various non-error corner cases around internal resolution.
+
+import "package:expect/expect.dart";
+
+/////////////////////////////////////////////////////////////////////////
+// Note: These imports may be deliberately unused. They bring certain
+// names into scope, in order to test that certain resolution choices are
+// made even in the presence of other symbols.
+/////////////////////////////////////////////////////////////////////////
+
+// Do Not Delete.
+// Bring global members into scope.
+import "helpers/global_scope.dart";
+
+// Do Not Delete.
+// Bring a class AGlobal with instance members and global members into scope.
+import "helpers/class_shadow.dart";
+
+extension GenericExtension<T> on T {
+ T get self => this;
+ void castToShadowedTypeParam<T>() {
+ dynamic s = self;
+ (s as T);
+ }
+
+ List<T> mkList() => <T>[];
+ void castToShadowedTypeList<T>() {
+ (mkList() as List<T>);
+ }
+}
+
+const bool extensionValue = true;
+
+void checkExtensionValue(bool x) {
+ Expect.equals(x, extensionValue);
+}
+
+extension StaticExt on AGlobal {
+ // Valid to overlap static names with the target type symbols
+ static bool get fieldInInstanceScope => extensionValue;
+ static bool get getterInInstanceScope => extensionValue;
+ static set setterInInstanceScope(bool x) {
+ checkExtensionValue(x);
+ }
+
+ static bool methodInInstanceScope() => extensionValue;
+
+ // Add the global symbols
+ static bool get fieldInGlobalScope => extensionValue;
+ static bool get getterInGlobalScope => extensionValue;
+ static set setterInGlobalScope(bool x) {
+ checkExtensionValue(x);
+ }
+
+ static bool methodInGlobalScope() => extensionValue;
+
+ void testNakedIdentifiers() {
+ // Symbols in the global scope and the local static scope resolve to
+ // the local static scope.
+ {
+ bool t0 = fieldInGlobalScope;
+ checkExtensionValue(t0);
+ bool t1 = getterInGlobalScope;
+ checkExtensionValue(t1);
+ setterInGlobalScope = extensionValue;
+ bool t2 = methodInGlobalScope();
+ checkExtensionValue(t2);
+ }
+
+ // Symbols in the global scope, the instance scope, and the local static scope
+ // resolve to the local static scope.
+ {
+ bool t0 = fieldInInstanceScope;
+ checkExtensionValue(t0);
+ bool t1 = getterInInstanceScope;
+ checkExtensionValue(t1);
+ setterInInstanceScope = extensionValue;
+ bool t2 = methodInInstanceScope();
+ checkExtensionValue(t2);
+ }
+ }
+
+ void instanceTest() {
+ StaticExt(this).testNakedIdentifiers();
+ }
+}
+
+void main() {
+ var a = new AGlobal();
+ a.instanceTest();
+
+ Expect.throwsTypeError(() => 3.castToShadowedTypeParam<String>());
+}
diff --git a/tests/language/extension_methods/static_extension_operators_test.dart b/tests/language/extension_methods/static_extension_operators_test.dart
new file mode 100644
index 0000000..20e0f0d
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_operators_test.dart
@@ -0,0 +1,130 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+import "package:expect/expect.dart";
+
+// Tests that static extensions can be used for all operators.
+
+void main() {
+ Object a = "a";
+ Object b = "b";
+ Object c = "c";
+
+ expect("(-a)", -a);
+ expect("(~a)", ~a);
+ expect("(a+b)", a + b);
+ expect("(a-b)", a - b);
+ expect("(a*b)", a * b);
+ expect("(a/b)", a / b);
+ expect("(a%b)", a % b);
+ expect("(a~/b)", a ~/ b);
+ expect("(a|b)", a | b);
+ expect("(a&b)", a & b);
+ expect("(a^b)", a ^ b);
+ expect("(a<b)", a < b);
+ expect("(a>b)", a > b);
+ expect("(a<=b)", a <= b);
+ expect("(a>=b)", a >= b);
+ expect("(a<<b)", a << b);
+ expect("(a>>b)", a >> b);
+ // expect("(a>>>b)", a >>> b);
+ expect("a(b)", a(b));
+ expect("a(b,c)", a(b, c));
+ expect("a[b]", a[b]);
+ expect("c", a[b] = c, "a[b]=c");
+
+ // Operator-assignment works and evaluates to its RHS value.
+ expect("(a.field+b)", a.field += b, "a.field=(a.field+b)");
+ expect("(a.field-b)", a.field -= b, "a.field=(a.field-b)");
+ expect("(a.field*b)", a.field *= b, "a.field=(a.field*b)");
+ expect("(a.field/b)", a.field /= b, "a.field=(a.field/b)");
+ expect("(a.field%b)", a.field %= b, "a.field=(a.field%b)");
+ expect("(a.field~/b)", a.field ~/= b, "a.field=(a.field~/b)");
+ expect("(a.field|b)", a.field |= b, "a.field=(a.field|b)");
+ expect("(a.field&b)", a.field &= b, "a.field=(a.field&b)");
+ expect("(a.field^b)", a.field ^= b, "a.field=(a.field^b)");
+ expect("(a.field<<b)", a.field <<= b, "a.field=(a.field<<b)");
+ expect("(a.field>>b)", a.field >>= b, "a.field=(a.field>>b)");
+ // expect("(a.field>>>b)", a.field >>>= b, "a.field=(a.field>>>b)");
+
+ // Even on index operations.
+ expect("(a[c]+b)", a[c] += b, "a[c]=(a[c]+b)");
+ expect("(a[c]-b)", a[c] -= b, "a[c]=(a[c]-b)");
+ expect("(a[c]*b)", a[c] *= b, "a[c]=(a[c]*b)");
+ expect("(a[c]/b)", a[c] /= b, "a[c]=(a[c]/b)");
+ expect("(a[c]%b)", a[c] %= b, "a[c]=(a[c]%b)");
+ expect("(a[c]~/b)", a[c] ~/= b, "a[c]=(a[c]~/b)");
+ expect("(a[c]|b)", a[c] |= b, "a[c]=(a[c]|b)");
+ expect("(a[c]&b)", a[c] &= b, "a[c]=(a[c]&b)");
+ expect("(a[c]^b)", a[c] ^= b, "a[c]=(a[c]^b)");
+ expect("(a[c]<<b)", a[c] <<= b, "a[c]=(a[c]<<b)");
+ expect("(a[c]>>b)", a[c] >>= b, "a[c]=(a[c]>>b)");
+ // expect("(a[c]>>>b)", a[c] >>>= b, "a[c]=(a[c]>>>b)");
+
+ // And ++/-- expands to their assignments.
+ expect("(a.field+1)", ++a.field, "a.field=(a.field+1)");
+ expect("(a.field-1)", --a.field, "a.field=(a.field-1)");
+ expect("a.field", a.field++, "a.field=(a.field+1)");
+ expect("a.field", a.field--, "a.field=(a.field-1)");
+ expect("(a[b]+1)", ++a[b], "a[b]=(a[b]+1)");
+ expect("(a[b]-1)", --a[b], "a[b]=(a[b]-1)");
+ expect("a[b]", a[b]++, "a[b]=(a[b]+1)");
+ expect("a[b]", a[b]--, "a[b]=(a[b]-1)");
+
+ // Combinations.
+ expect("(a+b[b(c)]((a*b)))", a + b[c[a] = b(c)](a * b), "c[a]=b(c)");
+
+ // Operator precedence is unaffected by being extensions.
+ expect("(c<((-a)|(b^((~c)&((a<<b)>>((c-a)+((((b*c)~/a)%b)/c)))))))",
+ c < -a | b ^ ~c & a << b >> c - a + b * c ~/ a % b / c);
+ expect("((((((((((((c/b)%a)~/c)*b)+a)-c)<<b)>>a)&(~c))^b)|(-a))>b)",
+ c / b % a ~/ c * b + a - c << b >> a & ~c ^ b | -a > b);
+}
+
+// Last value set by []= or setter.
+String setValue = "";
+
+void expect(String expect, Object value, [String? expectSet]) {
+ Expect.equals(expect, value, "value");
+ if (expectSet != null) Expect.equals(expectSet, setValue, "assignment");
+}
+
+extension Ops on Object {
+ Object operator -() => "(-${this})";
+ Object operator ~() => "(~${this})";
+ Object operator +(Object other) => "(${this}+$other)";
+ Object operator -(Object other) => "(${this}-$other)";
+ Object operator *(Object other) => "(${this}*$other)";
+ Object operator /(Object other) => "(${this}/$other)";
+ Object operator %(Object other) => "(${this}%$other)";
+ Object operator ~/(Object other) => "(${this}~/$other)";
+ Object operator |(Object other) => "(${this}|$other)";
+ Object operator &(Object other) => "(${this}&$other)";
+ Object operator ^(Object other) => "(${this}^$other)";
+ Object operator <(Object other) => "(${this}<$other)";
+ Object operator >(Object other) => "(${this}>$other)";
+ Object operator <=(Object other) => "(${this}<=$other)";
+ Object operator >=(Object other) => "(${this}>=$other)";
+ Object operator <<(Object other) => "(${this}<<$other)";
+ Object operator >>(Object other) => "(${this}>>$other)";
+ // TODO: enable `>>>` when it has been implemented.
+ // String operator >>>(Object other) => "(${this}>>>$other)";
+
+ // Cannot make an extension method for `==` because it's declared by Object.
+
+ Object operator [](Object other) => "${this}[$other]";
+ void operator []=(Object other, Object value) {
+ setValue = "${this}[$other]=$value";
+ }
+
+ Object call([arg1, arg2]) =>
+ "${this}(${[arg1, arg2].where((x) => x != null).join(",")})";
+
+ Object get field => "${this}.field";
+ void set field(Object other) {
+ setValue = "${this}.field=$other";
+ }
+}
diff --git a/tests/language/extension_methods/static_extension_prefix_double_import_test.dart b/tests/language/extension_methods/static_extension_prefix_double_import_test.dart
new file mode 100644
index 0000000..3df4552
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_prefix_double_import_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+import "helpers/on_object.dart";
+import "helpers/on_object.dart" as p2;
+
+void main() {
+ Object o = 1;
+ Expect.equals("object", o.onObject);
+}
diff --git a/tests/language/extension_methods/static_extension_prefix_import_conflict_test.dart b/tests/language/extension_methods/static_extension_prefix_import_conflict_test.dart
new file mode 100644
index 0000000..7f3993f
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_prefix_import_conflict_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+import "helpers/on_object.dart";
+import "helpers/also_on_object.dart" as p2;
+
+void main() {
+ Object o = 1;
+ o.onObject;
+ //^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The property 'onObject' is defined in multiple extensions for 'Object' and neither is more specific.
+}
diff --git a/tests/language/extension_methods/static_extension_prefix_import_show_test.dart b/tests/language/extension_methods/static_extension_prefix_import_show_test.dart
new file mode 100644
index 0000000..8f5cf73
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_prefix_import_show_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+import "helpers/on_object.dart" as p1 show OnObject;
+import "helpers/on_int.dart" as p2 show OnInt;
+
+void main() {
+ int i = 0;
+ Object o = i;
+ Expect.equals("int", i.onInt);
+ Expect.equals("int", i.onObject);
+ Expect.equals("object", o.onObject);
+}
diff --git a/tests/language/extension_methods/static_extension_prefix_import_test.dart b/tests/language/extension_methods/static_extension_prefix_import_test.dart
new file mode 100644
index 0000000..eba2e94
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_prefix_import_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+import "helpers/on_object.dart" as p1;
+import "helpers/on_int.dart" as p2;
+
+void main() {
+ int i = 0;
+ Object o = i;
+ Expect.equals("int", i.onInt);
+ Expect.equals("int", i.onObject);
+ Expect.equals("object", o.onObject);
+}
diff --git a/tests/language/extension_methods/static_extension_resolution_failures_test.dart b/tests/language/extension_methods/static_extension_resolution_failures_test.dart
new file mode 100644
index 0000000..f68d72b
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_resolution_failures_test.dart
@@ -0,0 +1,124 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+// Tests extension method resolution failures.
+
+import "package:expect/expect.dart";
+
+main() {
+ A a = C();
+ B1 b1 = C();
+ B2 b2 = C();
+ C c = C();
+
+ Expect.equals("EA.v1", a.v1);
+ Expect.equals("EB1.v1", b1.v1);
+ Expect.equals("EB2.v1", b2.v1);
+ Expect.equals("EC.v1", c.v1);
+
+ Expect.equals("EA.v2", a.v2);
+ Expect.equals("EB1.v2", b1.v2);
+ Expect.equals("EB2.v2", b2.v2);
+ // Cannot determine which of EB1 and EB2's v2 is more specific
+ c.v2;
+ //^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The property 'v2' is defined in multiple extensions for 'C' and neither is more specific.
+
+ Expect.equals("EA.v3", a.v3);
+ Expect.equals("EA.v3", b1.v3);
+ Expect.equals("EA.v3", b2.v3);
+ Expect.equals("EA.v3", c.v3);
+
+ Iterable<num> i_num = <int>[];
+ Iterable<int> ii = <int>[];
+ List<num> ln = <int>[];
+ List<int> li = <int>[];
+
+ // No `i_num` extension declared.
+ i_num.i_num;
+ // ^^^^^
+ // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
+ // [cfe] The getter 'i_num' isn't defined for the class 'Iterable<num>'.
+
+ Expect.equals("Iterable<int>.i_num", ii.i_num);
+ Expect.equals("List<num>.i_num", ln.i_num);
+
+ // Both apply, neither is more specific.
+ li.i_num;
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The property 'i_num' is defined in multiple extensions for 'List<int>' and neither is more specific.
+
+ // no most specific because both are equally specific.
+ c.cs;
+ //^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The property 'cs' is defined in multiple extensions for 'C' and neither is more specific.
+
+ // Both EIT.e1 and ELO.e1 apply, but their instantiated on
+ // types are incomparable, and hence this is an error.
+ ln.e1();
+ // ^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] The method 'e1' is defined in multiple extensions for 'List<num>' and neither is more specific.
+}
+
+// Diamond class hierarchy.
+class A {}
+
+class B1 implements A {}
+
+class B2 implements A {}
+
+class C implements B1, B2 {}
+
+extension EA on A {
+ String get v1 => "EA.v1";
+ String get v2 => "EA.v2";
+ String get v3 => "EA.v3";
+}
+
+extension EB1 on B1 {
+ String get v1 => "EB1.v1";
+ String get v2 => "EB1.v2";
+}
+
+extension EB2 on B2 {
+ String get v1 => "EB2.v1";
+ String get v2 => "EB2.v2";
+}
+
+extension EC on C {
+ String get v1 => "EC.v1";
+}
+
+// Iterable<num>, Iterable<int>, List<num> and List<int> also forms diamond
+// hierarchy.
+extension II on Iterable<int> {
+ String get i_num => "Iterable<int>.i_num";
+}
+
+extension LN on List<num> {
+ String get i_num => "List<num>.i_num";
+}
+
+// Two exactly identical `on` types.
+extension C1 on C {
+ String get cs => "C1.cs";
+}
+
+extension C2 on C {
+ String get cs => "C2.cs";
+}
+
+extension EIT<T> on Iterable<T> {
+ String e1() => "Iterable<T>.e1";
+}
+
+extension ELO on List<Object> {
+ String e1() => "List<Object>.e1";
+}
diff --git a/tests/language/extension_methods/static_extension_resolution_test.dart b/tests/language/extension_methods/static_extension_resolution_test.dart
new file mode 100644
index 0000000..e3dfcd2
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_resolution_test.dart
@@ -0,0 +1,232 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+import "package:expect/expect.dart";
+
+// Tests the resolution of multiple applicable extensions.
+
+String? lastSetterValue;
+
+class SuperTarget {}
+
+class Target<T> extends SuperTarget {
+ String targetMethod() => "targetMethod";
+ String get targetGetter => "targetGetter";
+ void set targetSetter(String argument) {
+ lastSetterValue = "targetSetter: $argument";
+ }
+}
+
+class SubTarget<T> extends Target<T> {
+ String subTargetMethod() => "subTargetMethod";
+ String get subTargetGetter => "subTargetGetter";
+ void set subTargetSetter(String argument) {
+ lastSetterValue = "subTargetSetter: $argument";
+ }
+}
+
+extension E1<T> on SubTarget<T> {
+ static String name = "SubTarget<T>";
+
+ String e1() => "$name.e1";
+
+ String targetMethod() => "$name.targetMethod";
+ String get targetGetter => "$name.targetGetter";
+ void set targetSetter(String value) {
+ lastSetterValue = "$name.targetSetter: $value";
+ }
+
+ String subTargetMethod() => "$name.subTargetMethod";
+ String get subTargetGetter => "$name.subTargetGetter";
+ void set subTargetSetter(String value) {
+ lastSetterValue = "$name.subTargetSetter: $value";
+ }
+
+ List<T> get typedList => <T>[];
+}
+
+extension E2 on SubTarget<Object> {
+ static String name = "SubTarget<Object>";
+
+ String e1() => "$name.e1";
+ String e2() => "$name.e2";
+
+ String targetMethod() => "$name.targetMethod";
+ String get targetGetter => "$name.targetGetter";
+ void set targetSetter(String value) {
+ lastSetterValue = "$name.targetSetter: $value";
+ }
+
+ String subTargetMethod() => "$name.subTargetMethod";
+ String get subTargetGetter => "$name.subTargetGetter";
+ void set subTargetSetter(String value) {
+ lastSetterValue = "$name.subTargetSetter: $value";
+ }
+}
+
+extension E3<T> on Target<T> {
+ static String name = "Target<T>";
+
+ String e1() => "$name.e1";
+ String e2() => "$name.e2";
+ String e3() => "$name.e3";
+
+ String targetMethod() => "$name.targetMethod";
+ String get targetGetter => "$name.targetGetter";
+ void set targetSetter(String value) {
+ lastSetterValue = "$name.targetSetter: $value";
+ }
+
+ String subTargetMethod() => "$name.subTargetMethod";
+ String get subTargetGetter => "$name.subTargetGetter";
+ void set subTargetSetter(String value) {
+ lastSetterValue = "$name.subTargetSetter: $value";
+ }
+
+ List<T> get typedList => <T>[];
+}
+
+extension E4 on Target<Object> {
+ static String name = "Target<Object>";
+
+ String e1() => "$name.e1";
+ String e2() => "$name.e2";
+ String e3() => "$name.e3";
+ String e4() => "$name.e4";
+
+ String targetMethod() => "$name.targetMethod";
+ String get targetGetter => "$name.targetGetter";
+ void set targetSetter(String value) {
+ lastSetterValue = "$name.targetSetter: $value";
+ }
+
+ String subTargetMethod() => "$name.subTargetMethod";
+ String get subTargetGetter => "$name.subTargetGetter";
+ void set subTargetSetter(String value) {
+ lastSetterValue = "$name.subTargetSetter: $value";
+ }
+}
+
+extension E5<T> on T {
+ static String name = "T";
+
+ String e1() => "$name.e1";
+ String e2() => "$name.e2";
+ String e3() => "$name.e3";
+ String e4() => "$name.e4";
+ String e5() => "$name.e5";
+
+ String targetMethod() => "$name.targetMethod";
+ String get targetGetter => "$name.targetGetter";
+ void set targetSetter(String value) {
+ lastSetterValue = "$name.targetSetter: $value";
+ }
+
+ String subTargetMethod() => "$name.subTargetMethod";
+ String get subTargetGetter => "$name.subTargetGetter";
+ void set subTargetSetter(String value) {
+ lastSetterValue = "$name.subTargetSetter: $value";
+ }
+
+ List<T> get typedList => <T>[];
+}
+
+extension E6 on Object {
+ static String name = "Object";
+
+ String e1() => "$name.e1";
+ String e2() => "$name.e2";
+ String e3() => "$name.e3";
+ String e4() => "$name.e4";
+ String e5() => "$name.e5";
+ String e6() => "$name.e6";
+
+ String targetMethod() => "$name.targetMethod";
+ String get targetGetter => "$name.targetGetter";
+ void set targetSetter(String value) {
+ lastSetterValue = "$name.targetSetter: $value";
+ }
+
+ String subTargetMethod() => "$name.subTargetMethod";
+ String get subTargetGetter => "$name.subTargetGetter";
+ void set subTargetSetter(String value) {
+ lastSetterValue = "$name.subTargetSetter: $value";
+ }
+}
+
+main() {
+ SubTarget<num> s1 = SubTarget<int>();
+ Target<num> t1 = SubTarget<int>();
+ SuperTarget o1 = SubTarget<int>();
+ Target<int> ti1 = SubTarget<int>();
+ ;
+ SubTarget<int> si1 = SubTarget<int>();
+ ;
+
+ // Interface methods take precedence.
+
+ Expect.equals("targetGetter", s1.targetGetter);
+ Expect.equals("targetMethod", s1.targetMethod());
+ s1.targetSetter = "1";
+ Expect.equals("targetSetter: 1", lastSetterValue);
+
+ Expect.equals("subTargetGetter", s1.subTargetGetter);
+ Expect.equals("subTargetMethod", s1.subTargetMethod());
+ s1.subTargetSetter = "2";
+ Expect.equals("subTargetSetter: 2", lastSetterValue);
+
+ Expect.equals("targetGetter", t1.targetGetter);
+ Expect.equals("targetMethod", t1.targetMethod());
+ t1.targetSetter = "3";
+ Expect.equals("targetSetter: 3", lastSetterValue);
+
+ // Methods not on the instance resolve to extension methods.
+
+ Expect.equals("Target<T>.subTargetGetter", t1.subTargetGetter);
+ Expect.equals("Target<T>.subTargetMethod", t1.subTargetMethod());
+ t1.subTargetSetter = "4";
+ Expect.equals("Target<T>.subTargetSetter: 4", lastSetterValue);
+
+ Expect.type<List<int>>(ti1.typedList);
+ Expect.type<List<int>>(si1.typedList);
+ Expect.type<List<SuperTarget>>(o1.typedList);
+
+ // Extension methods can be called directly using override syntax.
+
+ Expect.equals("SubTarget<T>.targetGetter", E1<num>(si1).targetGetter);
+ Expect.equals("SubTarget<T>.targetMethod", E1<num>(si1).targetMethod());
+ E1<num>(si1).targetSetter = "5";
+ Expect.equals("SubTarget<T>.targetSetter: 5", lastSetterValue);
+
+ Expect.equals("SubTarget<T>.subTargetGetter", E1<num>(si1).subTargetGetter);
+ Expect.equals("SubTarget<T>.subTargetMethod", E1<num>(si1).subTargetMethod());
+ E1<num>(si1).subTargetSetter = "6";
+ Expect.equals("SubTarget<T>.subTargetSetter: 6", lastSetterValue);
+
+ Expect.type<List<num>>(E1<num>(si1).typedList);
+
+ // Applicable methods.
+ Expect.equals("SubTarget<T>.e1", s1.e1());
+ Expect.equals("T.e2", s1.e2());
+ Expect.equals("T.e3", s1.e3());
+ Expect.equals("T.e4", s1.e4());
+ Expect.equals("T.e5", s1.e5());
+ Expect.equals("Object.e6", s1.e6());
+
+ Expect.equals("Target<T>.e1", t1.e1());
+ Expect.equals("Target<T>.e2", t1.e2());
+ Expect.equals("Target<T>.e3", t1.e3());
+ Expect.equals("T.e4", t1.e4());
+ Expect.equals("T.e5", t1.e5());
+ Expect.equals("Object.e6", t1.e6());
+
+ Expect.equals("T.e1", o1.e1());
+ Expect.equals("T.e2", o1.e2());
+ Expect.equals("T.e3", o1.e3());
+ Expect.equals("T.e4", o1.e4());
+ Expect.equals("T.e5", o1.e5());
+ Expect.equals("Object.e6", o1.e6());
+}
diff --git a/tests/language/extension_methods/static_extension_setter_getter_assignability_error_test.dart b/tests/language/extension_methods/static_extension_setter_getter_assignability_error_test.dart
new file mode 100644
index 0000000..f7cc524
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_setter_getter_assignability_error_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+// It is an error to have a setter and a getter in an extension where
+// the return type of the getter is not assignable to the argument type
+// of the setter.
+extension E1 on int {
+ static int get property => 1;
+ // ^^
+ // [cfe] unspecified
+ // ^^^^^^^^
+ // [analyzer] STATIC_WARNING.GETTER_NOT_SUBTYPE_SETTER_TYPES
+ static void set property(String value) {}
+ // ^^
+ // [cfe] unspecified
+ int get property2 => 1;
+ // ^^
+ // [cfe] unspecified
+ // ^^^^^^^^^
+ // [analyzer] STATIC_WARNING.GETTER_NOT_SUBTYPE_SETTER_TYPES
+ void set property2(String x) {}
+ // ^^
+ // [cfe] unspecified
+}
+
+void main() {}
diff --git a/tests/language/extension_methods/static_extension_silly_types_test.dart b/tests/language/extension_methods/static_extension_silly_types_test.dart
new file mode 100644
index 0000000..cbe21d6
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_silly_types_test.dart
@@ -0,0 +1,158 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+// Tests extension methods on the non-function, non-class types.
+
+import "dart:async" show FutureOr;
+
+import "package:expect/expect.dart";
+
+void main() {
+ M m = C();
+ Object o = Object();
+ Function fun = () => null;
+ f() => 0;
+ String f1(int x) => "$x";
+ String f2([int x = 0, int y = 0]) => "${x + y}";
+ int i = 0;
+ Future<int> fi = Future<int>.value(0);
+ Future<Future<int>> ffi = Future<Future<int>>.value(fi);
+ FutureOr<FutureOr<int>> foi = 1;
+ Future<Null> fn = Future<Null>.value(null);
+ Null n = null;
+
+ // `on M` matches mixin interface.
+ Expect.equals(1, m.m);
+ // `on void` matches anything.
+ Expect.equals(2, o.v);
+ Expect.equals(2, n.v);
+ // `on dynamic` matches anything.
+ Expect.equals(3, o.d);
+ Expect.equals(3, n.d);
+ // `on Function` matches any function type and Function itself.
+ Expect.equals(4, f.f);
+ Expect.equals(4, fun.f);
+ Expect.equals(4, f1.f);
+ Expect.equals(4, f2.f);
+ // `on <function type>` matches those functions.
+ Expect.equals(5, f1.fu);
+ Expect.equals(5, f2.fu);
+ // `on FutureOr<int>` matches both future and not.
+ Expect.equals(6, i.fi);
+ Expect.equals(6, fi.fi);
+ // `on FutureOr<Object>` matches everything.
+ Expect.equals(7, o.fo);
+ Expect.equals(7, n.fo);
+ // `on FutureOr<Future<Object>>` matches any future or futureOr.
+ Expect.equals(8, fi.ffo);
+ Expect.equals(8, ffi.ffo);
+ // `on FutureOr<Null>` matches Null and FutureOr<Null>.
+ Expect.equals(9, fn.fn);
+ Expect.equals(9, n.fn);
+ // `on Null` does match null. No errors for receiver being null.
+ Expect.equals(10, n.n);
+
+ // Matching can deconstruct static function types.
+ Expect.equals(int, f1.parameterType);
+ Expect.equals(String, f1.returnType);
+ Expect.equals(int, f2.parameterType);
+ Expect.equals(String, f2.returnType);
+ // And static FutureOr types.
+ Expect.equals(int, i.futureType);
+ Expect.equals(int, fi.futureType);
+ Expect.equals(type<Future<int>>(), ffi.futureType);
+ Expect.equals(type<FutureOr<int>>(), foi.futureType);
+ // TODO: Update and enable when
+ // https://github.com/dart-lang/language/issues/436
+ // is resolved.
+ // Expect.equals(dynamic, n.futureType); // Inference treats `null` as no hint.
+}
+
+Type type<T>() => T;
+
+mixin M {}
+
+class C = Object with M;
+
+extension on M {
+ int get m => 1;
+}
+
+extension on void {
+ int get v => 2;
+ testVoid() {
+ // No access on void. Static type of `this` is void!
+ this //
+ .toString() //# 01: compile-time error
+ ;
+ }
+}
+
+extension on dynamic {
+ int get d => 3;
+
+ void testDynamic() {
+ // Static type of `this` is dynamic, allows dynamic invocation.
+ this.arglebargle();
+ }
+}
+
+extension on Function {
+ int get f => 4;
+
+ void testFunction() {
+ // Static type of `this` is Function. Allows any dynamic invocation.
+ this();
+ this(1);
+ this(x: 1);
+ // No function can have both optional positional and named parameters.
+ }
+}
+
+extension on String Function(int) {
+ int get fu => 5;
+}
+
+extension on FutureOr<int> {
+ int get fi => 6;
+
+ void testFutureOr() {
+ var self = this;
+ // The `this` type can be type-promoted to both Future<int> and int.
+ if (self is Future<int>) {
+ self.then((int x) {});
+ } else if (self is int) {
+ self + 2;
+ }
+ }
+}
+
+extension on FutureOr<Object?> {
+ int get fo => 7;
+}
+
+extension on FutureOr<Future<Object?>> {
+ int get ffo => 8;
+}
+
+extension on FutureOr<Null> {
+ int get fn => 9;
+}
+
+extension on Null {
+ int get n => 10;
+}
+
+// TODO: Type `Never` when it's added.
+
+extension<T> on FutureOr<T> {
+ Type get futureType => T;
+}
+
+extension<R, T> on R Function(T) {
+ Type get returnType => R;
+ Type get parameterType => T;
+}
diff --git a/tests/language/extension_methods/static_extension_syntax_test.dart b/tests/language/extension_methods/static_extension_syntax_test.dart
new file mode 100644
index 0000000..0d71b60
--- /dev/null
+++ b/tests/language/extension_methods/static_extension_syntax_test.dart
@@ -0,0 +1,162 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+// Tests extension declaration syntax combinations.
+
+import "package:expect/expect.dart";
+
+void checkStaticType<T>(T x) {
+ Expect.type<T>(x);
+}
+
+main() {
+ Object object = <int>[];
+ List<Object> list = <int>[];
+ List<num> numList = <int>[];
+ Pair<int, double> numPair = Pair(1, 2.5);
+ RecSolution recs = RecSolution();
+
+ Expect.equals(0, object.e0);
+ Expect.equals(0, list.e0);
+
+ Expect.equals(1, object.e1);
+ Expect.equals(1, list.e1);
+
+ Expect.equals(0, object.e4);
+ Expect.equals(0, list.e4);
+ Expect.equals(4, numList.e4);
+
+ Expect.equals(0, object.e5);
+ Expect.equals(0, list.e5);
+ Expect.equals(5, numList.e5);
+
+ Expect.equals(0, object.e6);
+ Expect.equals(6, list.e6);
+ Expect.equals(6, numList.e6);
+ checkStaticType<List<num>>(numList.list6);
+
+ Expect.equals(0, object.e7);
+ Expect.equals(7, list.e7);
+ Expect.equals(7, numList.e7);
+ checkStaticType<List<num>>(numList.list7);
+
+ Expect.equals(10, object.e10);
+ Expect.equals(10, numList.e10);
+ checkStaticType<List<Object>>(object.list10);
+ checkStaticType<List<List<num>>>(numList.list10);
+
+ Expect.equals(11, object.e11);
+ Expect.equals(11, numList.e11);
+ checkStaticType<List<Object>>(object.list11);
+ checkStaticType<List<List<num>>>(numList.list11);
+
+ Expect.equals(0, object.e14);
+ Expect.equals(14, numPair.e14);
+ Expect.type<List<num>>(numPair.list14);
+ checkStaticType<List<num>>(numPair.list14);
+
+ Expect.equals(0, object.e16);
+ Expect.equals(16, numPair.e16);
+ Expect.type<Map<int, double>>(numPair.map16);
+ checkStaticType<Map<int, double>>(numPair.map16);
+
+ Expect.equals(0, object.e17);
+ Expect.equals(0, list.e17);
+ Expect.equals(17, numList.e17);
+ Expect.type<List<num>>(numList.list17);
+ checkStaticType<List<num>>(numList.list17);
+
+ Expect.equals(0, object.e19);
+ Expect.equals(19, recs.e19);
+ Expect.type<List<RecSolution>>(recs.list19);
+ checkStaticType<List<RecSolution>>(recs.list19);
+
+ Expect.equals(0, object.e20);
+ Expect.equals(20, recs.e20);
+ Expect.type<List<RecSolution>>(recs.list20);
+ checkStaticType<List<RecSolution>>(recs.list20);
+}
+
+extension on Object {
+ int get e0 => 0;
+ // Fallbacks to test cases where other extensions do not apply.
+ int get e4 => 0;
+ int get e5 => 0;
+ int get e6 => 0;
+ int get e7 => 0;
+ int get e14 => 0;
+ int get e16 => 0;
+ int get e17 => 0;
+ int get e19 => 0;
+ int get e20 => 0;
+}
+
+extension E1 on Object {
+ int get e1 => 1;
+}
+
+extension on List<num> {
+ int get e4 => 4;
+}
+
+extension E5 on List<num> {
+ int get e5 => 5;
+}
+
+extension<T> on List<T> {
+ int get e6 => 6;
+ List<T> get list6 => <T>[];
+}
+
+extension E7<T> on List<T> {
+ int get e7 => 7;
+ List<T> get list7 => <T>[];
+}
+
+extension<T> on T {
+ int get e10 => 10;
+ List<T> get list10 => <T>[];
+}
+
+extension E11<T> on T {
+ int get e11 => 11;
+ List<T> get list11 => <T>[];
+}
+
+extension<T> on Pair<T, T> {
+ int get e14 => 14;
+ List<T> get list14 => <T>[];
+}
+
+extension E16<S, T> on Pair<S, T> {
+ int get e16 => 16;
+ Map<S, T> get map16 => <S, T>{};
+}
+
+extension<T extends num> on List<T> {
+ int get e17 => 17;
+ List<T> get list17 => <T>[];
+}
+
+extension<T extends Rec<T>> on T {
+ int get e19 => 19;
+ List<T> get list19 => <T>[];
+}
+
+extension E20<T extends Rec<T>> on T {
+ int get e20 => 20;
+ List<T> get list20 => <T>[];
+}
+
+class Pair<A, B> {
+ final A first;
+ final B second;
+ const Pair(this.first, this.second);
+}
+
+class Rec<T extends Rec<T>> {}
+
+class RecSolution extends Rec<RecSolution> {}
diff --git a/tests/language/extension_methods/syntax/extension_methods_test.dart b/tests/language/extension_methods/syntax/extension_methods_test.dart
new file mode 100644
index 0000000..51013db
--- /dev/null
+++ b/tests/language/extension_methods/syntax/extension_methods_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+import 'package:expect/expect.dart';
+
+class C {
+ int get one => 1;
+}
+
+extension E on C {
+ int get two => 2;
+}
+
+main() {
+ C c = C();
+ var result = c.one + c.two;
+ Expect.equals(result, 3);
+}
diff --git a/tests/language/function_subtype/regress41680_strong_test.dart b/tests/language/function_subtype/regress41680_strong_test.dart
new file mode 100644
index 0000000..f8b79e1
--- /dev/null
+++ b/tests/language/function_subtype/regress41680_strong_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Requirements=nnbd-strong
+
+import "package:expect/expect.dart";
+
+typedef dynamicToDynamic = dynamic Function(dynamic);
+
+typedef voidToT = T Function<T>();
+
+dynamic dynamicNull = null;
+
+cast<T>(dynamic value) => value as T;
+
+bool allowsArgument(T Function<T>() fn) => true;
+
+main() {
+ // In strong mode Null is not a subtype of function types.
+ Expect.throwsTypeError(() => dynamicNull as Function);
+ Expect.throwsTypeError(() => dynamicNull as dynamicToDynamic);
+ Expect.throwsTypeError(() => cast<dynamic Function(dynamic)>(dynamicNull));
+ Expect.throwsTypeError(() => dynamicNull as voidToT);
+ Expect.throwsTypeError(() => allowsArgument(dynamicNull));
+}
diff --git a/tests/language/function_subtype/regress41680_weak_test.dart b/tests/language/function_subtype/regress41680_weak_test.dart
new file mode 100644
index 0000000..570ccd5
--- /dev/null
+++ b/tests/language/function_subtype/regress41680_weak_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Requirements=nnbd-weak
+
+import "package:expect/expect.dart";
+
+typedef dynamicToDynamic = dynamic Function(dynamic);
+
+typedef voidToT = T Function<T>();
+
+dynamic dynamicNull = null;
+
+dynamic cast<T>(dynamic value) => value as T;
+
+bool allowsArgument(T Function<T>() fn) => true;
+
+main() {
+ // In weak mode Null should be allowed as a subtype of function types.
+ Expect.equals(null, dynamicNull as Function);
+ Expect.equals(null, dynamicNull as dynamicToDynamic);
+ Expect.equals(null, cast<dynamic Function(dynamic)>(dynamicNull));
+ Expect.equals(null, dynamicNull as voidToT);
+ Expect.equals(true, allowsArgument(dynamicNull));
+}
diff --git a/tests/language/nnbd/boolean_conversion/boolean_conversion_error_test.dart b/tests/language/nnbd/boolean_conversion/boolean_conversion_error_test.dart
index 50ca7b0..695dfa3 100644
--- a/tests/language/nnbd/boolean_conversion/boolean_conversion_error_test.dart
+++ b/tests/language/nnbd/boolean_conversion/boolean_conversion_error_test.dart
@@ -57,47 +57,47 @@
if (nil) {}
// ^^^
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
- // [cfe] A value of type 'Null?' can't be assigned to a variable of type 'bool'.
+ // [cfe] A value of type 'Null' can't be assigned to a variable of type 'bool'.
[if (nil) 3];
// ^^^
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
- // [cfe] A value of type 'Null?' can't be assigned to a variable of type 'bool'.
+ // [cfe] A value of type 'Null' can't be assigned to a variable of type 'bool'.
nil ? 3 : 4;
// ^^^
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
-// [cfe] A value of type 'Null?' can't be assigned to a variable of type 'bool'.
+// [cfe] A value of type 'Null' can't be assigned to a variable of type 'bool'.
while (nil) {}
// ^^^
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
- // [cfe] A value of type 'Null?' can't be assigned to a variable of type 'bool'.
+ // [cfe] A value of type 'Null' can't be assigned to a variable of type 'bool'.
do {} while (nil);
// ^^^
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
- // [cfe] A value of type 'Null?' can't be assigned to a variable of type 'bool'.
+ // [cfe] A value of type 'Null' can't be assigned to a variable of type 'bool'.
nil || true;
// ^^^
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_OPERAND
-// [cfe] A value of type 'Null?' can't be assigned to a variable of type 'bool'.
+// [cfe] A value of type 'Null' can't be assigned to a variable of type 'bool'.
nil && true;
// ^^^
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_OPERAND
-// [cfe] A value of type 'Null?' can't be assigned to a variable of type 'bool'.
+// [cfe] A value of type 'Null' can't be assigned to a variable of type 'bool'.
true || nil;
// ^^^
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_OPERAND
- // [cfe] A value of type 'Null?' can't be assigned to a variable of type 'bool'.
+ // [cfe] A value of type 'Null' can't be assigned to a variable of type 'bool'.
true && nil;
// ^^^
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_OPERAND
- // [cfe] A value of type 'Null?' can't be assigned to a variable of type 'bool'.
+ // [cfe] A value of type 'Null' can't be assigned to a variable of type 'bool'.
for (int i = 0; nil; i++) {}
// ^^^
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
- // [cfe] A value of type 'Null?' can't be assigned to a variable of type 'bool'.
+ // [cfe] A value of type 'Null' can't be assigned to a variable of type 'bool'.
[for (int i = 0; nil; i++) 3];
// ^^^
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
- // [cfe] A value of type 'Null?' can't be assigned to a variable of type 'bool'.
+ // [cfe] A value of type 'Null' can't be assigned to a variable of type 'bool'.
}
{
// Check that values of type `Object` are not usable as booleans.
diff --git a/tests/language/nnbd/never/never_null_assignability_error_test.dart b/tests/language/nnbd/never/never_null_assignability_error_test.dart
index 634e219..5c745a6 100644
--- a/tests/language/nnbd/never/never_null_assignability_error_test.dart
+++ b/tests/language/nnbd/never/never_null_assignability_error_test.dart
@@ -28,7 +28,7 @@
takesNever(nil);
// ^^^
// [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
- // [cfe] The argument type 'Null?' can't be assigned to the parameter type 'Never'.
+ // [cfe] The argument type 'Null' can't be assigned to the parameter type 'Never'.
takesNever(never);
takesNever(3 as dynamic);
(takesNever as dynamic)(3);
@@ -40,7 +40,7 @@
takesInt(nil);
// ^^^
// [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
- // [cfe] The argument type 'Null?' can't be assigned to the parameter type 'int'.
+ // [cfe] The argument type 'Null' can't be assigned to the parameter type 'int'.
takesInt(nil as dynamic);
(takesInt as dynamic)(nil);
(takesInt as dynamic)("hello");
@@ -52,7 +52,7 @@
takesObject(nil);
// ^^^
// [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
- // [cfe] The argument type 'Null?' can't be assigned to the parameter type 'Object'.
+ // [cfe] The argument type 'Null' can't be assigned to the parameter type 'Object'.
takesObject(nil as dynamic);
(takesObject as dynamic)(nil);
}
@@ -74,17 +74,17 @@
applyTakesNull(takesNever, nil);
// ^^^^^^^^^^
// [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
- // [cfe] The argument type 'void Function(Never)' can't be assigned to the parameter type 'void Function(Null?)'.
+ // [cfe] The argument type 'void Function(Never)' can't be assigned to the parameter type 'void Function(Null)'.
applyTakesNull(takesAny, nil);
applyTakesNull(takesInt, nil);
// ^^^^^^^^
// [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
- // [cfe] The argument type 'void Function(int)' can't be assigned to the parameter type 'void Function(Null?)'.
+ // [cfe] The argument type 'void Function(int)' can't be assigned to the parameter type 'void Function(Null)'.
applyTakesNull(takesObject, nil);
// ^^^^^^^^^^^
// [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
- // [cfe] The argument type 'void Function(Object)' can't be assigned to the parameter type 'void Function(Null?)'.
+ // [cfe] The argument type 'void Function(Object)' can't be assigned to the parameter type 'void Function(Null)'.
}
// Test applying a null safe function of static type void Function(Null)
@@ -95,15 +95,15 @@
applyTakesNull(takesNever, 3);
// ^^^^^^^^^^
// [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
- // [cfe] The argument type 'void Function(Never)' can't be assigned to the parameter type 'void Function(Null?)'.
+ // [cfe] The argument type 'void Function(Never)' can't be assigned to the parameter type 'void Function(Null)'.
applyTakesNull(takesInt, 3);
// ^^^^^^^^
// [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
- // [cfe] The argument type 'void Function(int)' can't be assigned to the parameter type 'void Function(Null?)'.
+ // [cfe] The argument type 'void Function(int)' can't be assigned to the parameter type 'void Function(Null)'.
applyTakesNull(takesObject, 3);
// ^^^^^^^^^^^
// [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
- // [cfe] The argument type 'void Function(Object)' can't be assigned to the parameter type 'void Function(Null?)'.
+ // [cfe] The argument type 'void Function(Object)' can't be assigned to the parameter type 'void Function(Null)'.
applyTakesNull(takesAny, 3);
}
@@ -139,16 +139,16 @@
applyTakesNullDynamically(takesNever, nil);
// ^^^^^^^^^^
// [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
- // [cfe] The argument type 'void Function(Never)' can't be assigned to the parameter type 'void Function(Null?)'.
+ // [cfe] The argument type 'void Function(Never)' can't be assigned to the parameter type 'void Function(Null)'.
applyTakesNullDynamically(takesAny, nil);
applyTakesNullDynamically(takesInt, nil);
// ^^^^^^^^
// [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
- // [cfe] The argument type 'void Function(int)' can't be assigned to the parameter type 'void Function(Null?)'.
+ // [cfe] The argument type 'void Function(int)' can't be assigned to the parameter type 'void Function(Null)'.
applyTakesNullDynamically(takesObject, nil);
// ^^^^^^^^^^^
// [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
- // [cfe] The argument type 'void Function(Object)' can't be assigned to the parameter type 'void Function(Null?)'.
+ // [cfe] The argument type 'void Function(Object)' can't be assigned to the parameter type 'void Function(Null)'.
}
// Test dynamically applying a null safe function of static type
@@ -159,19 +159,19 @@
applyTakesNullDynamically(takesNever, 3);
// ^^^^^^^^^^
// [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
- // [cfe] The argument type 'void Function(Never)' can't be assigned to the parameter type 'void Function(Null?)'.
+ // [cfe] The argument type 'void Function(Never)' can't be assigned to the parameter type 'void Function(Null)'.
applyTakesNullDynamically(takesInt, 3);
// ^^^^^^^^
// [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
- // [cfe] The argument type 'void Function(int)' can't be assigned to the parameter type 'void Function(Null?)'.
+ // [cfe] The argument type 'void Function(int)' can't be assigned to the parameter type 'void Function(Null)'.
applyTakesNullDynamically(takesInt, "hello");
// ^^^^^^^^
// [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
- // [cfe] The argument type 'void Function(int)' can't be assigned to the parameter type 'void Function(Null?)'.
+ // [cfe] The argument type 'void Function(int)' can't be assigned to the parameter type 'void Function(Null)'.
applyTakesNullDynamically(takesObject, 3);
// ^^^^^^^^^^^
// [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
- // [cfe] The argument type 'void Function(Object)' can't be assigned to the parameter type 'void Function(Null?)'.
+ // [cfe] The argument type 'void Function(Object)' can't be assigned to the parameter type 'void Function(Null)'.
applyTakesNullDynamically(takesAny, 3);
}
@@ -204,12 +204,12 @@
// ^
// [analyzer] unspecified
// ^
- // [cfe] A value of type 'Null?' can't be assigned to a variable of type 'Never'.
+ // [cfe] A value of type 'Null' can't be assigned to a variable of type 'Never'.
never = nil;
// ^
// [analyzer] unspecified
// ^
- // [cfe] A value of type 'Null?' can't be assigned to a variable of type 'Never'.
+ // [cfe] A value of type 'Null' can't be assigned to a variable of type 'Never'.
nil = never;
testNullSafeCalls();
testNullSafeApply();
diff --git a/tests/language/nnbd/type_promotion/promoted_lhs_used_as_assignment_context_test.dart b/tests/language/nnbd/type_promotion/promoted_lhs_used_as_assignment_context_test.dart
new file mode 100644
index 0000000..245ec8b
--- /dev/null
+++ b/tests/language/nnbd/type_promotion/promoted_lhs_used_as_assignment_context_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+import 'package:expect/expect.dart';
+
+void f(Object x) {
+ if (x is double) {
+ // The context for the RHS of the assignment should be `double`, so the `1`
+ // should be converted to `1.0`, and thus `x` should remain promoted and
+ // the call to `g` should be statically ok.
+ x = 1;
+ g(x);
+ // Furthermore, at runtime, the value of x should be a double.
+ Expect.isTrue(x is double);
+ // However, the context is only advisory; it is still ok to assign a
+ // non-double (un-doing the promotion).
+ x = 'foo';
+ Expect.isTrue(x is String);
+ }
+}
+
+void g(double x) {}
+
+main() {
+ f(1.0);
+}
diff --git a/tests/language_2/async/return_types_test.dart b/tests/language_2/async/return_types_test.dart
index 659d275..4ecd5b4 100644
--- a/tests/language_2/async/return_types_test.dart
+++ b/tests/language_2/async/return_types_test.dart
@@ -19,7 +19,7 @@
return "String";
// ^^^^^^^^
// [analyzer] STATIC_TYPE_WARNING.RETURN_OF_INVALID_TYPE
- // [cfe] A value of type 'String' can't be assigned to a variable of type 'FutureOr<int>'.
+ // [cfe] A value of type 'Future<String>' can't be assigned to a variable of type 'FutureOr<int>'.
}
Future<int, String>
diff --git a/tests/language_2/function_subtype/regress41680_test.dart b/tests/language_2/function_subtype/regress41680_test.dart
new file mode 100644
index 0000000..e4d689d
--- /dev/null
+++ b/tests/language_2/function_subtype/regress41680_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+typedef dynamicToDynamic = dynamic Function(dynamic);
+
+typedef voidToT = T Function<T>();
+
+dynamic dynamicNull = null;
+
+dynamic cast<T>(dynamic value) => value as T;
+
+bool allowsArgument(T Function<T>() fn) => true;
+
+main() {
+ // In legacy Dart 2 Null should be allowed as a subtype of function types.
+ Expect.equals(null, dynamicNull as Function);
+ Expect.equals(null, dynamicNull as dynamicToDynamic);
+ Expect.equals(null, cast<dynamic Function(dynamic)>(dynamicNull));
+ Expect.equals(null, dynamicNull as voidToT);
+ Expect.equals(true, allowsArgument(dynamicNull));
+}
diff --git a/tests/language_2/vm/regress_flutter_55345_const_test.dart b/tests/language_2/vm/regress_flutter_55345_const_test.dart
new file mode 100644
index 0000000..9b548ff
--- /dev/null
+++ b/tests/language_2/vm/regress_flutter_55345_const_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Verifies that references to deduplicated mixins are properly updated
+// in types which are only accessible through constants.
+// Regression test for https://github.com/flutter/flutter/issues/55345.
+
+class Diagnosticable {}
+
+class SomeClass with Diagnosticable {}
+
+class State<T> with Diagnosticable {
+ const State();
+}
+
+class StateA extends State {
+ const StateA();
+}
+
+class StateB extends State<int> {
+ const StateB();
+}
+
+const c1 = StateA();
+const c2 = StateB();
+
+main() {
+ print(const [
+ {
+ (c1 ?? c2): [
+ [c1 ?? c2]
+ ]
+ },
+ 'abc'
+ ]);
+}
diff --git a/tests/language_2/vm/regress_flutter_55345_test.dart b/tests/language_2/vm/regress_flutter_55345_test.dart
new file mode 100644
index 0000000..f5ee00a
--- /dev/null
+++ b/tests/language_2/vm/regress_flutter_55345_test.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Verifies that references to deduplicated mixins are properly updated.
+// Regression test for https://github.com/flutter/flutter/issues/55345.
+
+class Diagnosticable {}
+
+class SomeClass with Diagnosticable {}
+
+class State<T> with Diagnosticable {}
+
+class StateA extends State {}
+
+class StateB extends State<int> {}
+
+StateA a = StateA();
+StateB b = StateB();
+
+List<T> foo<T>(T x) {
+ print(T);
+ return <T>[x];
+}
+
+T Function<S extends T>(T) bar<T>(T x) {
+ print(T);
+
+ return <S extends T>(T y) {
+ print(S);
+ print(y);
+ return y;
+ };
+}
+
+main() {
+ State x1 = a ?? b;
+ print(x1);
+
+ var x2 = a ?? b;
+ var x3 = foo(x2);
+ var x4 = bar(x3);
+ x4(x3);
+}
diff --git a/tests/lib/async/regress154963234_strong_test.dart b/tests/lib/async/regress154963234_strong_test.dart
new file mode 100644
index 0000000..d2e537b
--- /dev/null
+++ b/tests/lib/async/regress154963234_strong_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Requirements=nnbd-strong
+
+import "package:expect/expect.dart";
+
+main() {
+ var shortDuration = Duration(milliseconds: 5);
+
+ Expect.isTrue(Future<int?>.delayed(shortDuration) is Future);
+ // In strong mode not passing a computation will throw when the type argument
+ // passed is not nullable.
+ Expect.throwsArgumentError(() => Future<int>.delayed(shortDuration));
+}
diff --git a/tests/lib/async/regress154963234_weak_test.dart b/tests/lib/async/regress154963234_weak_test.dart
new file mode 100644
index 0000000..0c689f7
--- /dev/null
+++ b/tests/lib/async/regress154963234_weak_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Requirements=nnbd-weak
+
+import "package:expect/expect.dart";
+
+main() {
+ var shortDuration = Duration(milliseconds: 5);
+
+ Expect.isTrue(Future<int?>.delayed(shortDuration) is Future);
+ // In weak mode passing computation is not required because any type passed as
+ // the type argument can be nullable.
+ Expect.isTrue(Future<int>.delayed(shortDuration) is Future);
+}
diff --git a/tests/lib/isolate/no_package_test.dart b/tests/lib/isolate/no_package_test.dart
new file mode 100644
index 0000000..833e56b
--- /dev/null
+++ b/tests/lib/isolate/no_package_test.dart
@@ -0,0 +1,67 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:io";
+import "package:async_helper/async_minitest.dart";
+
+void testNoPackages(String filePath, String uri, String expected) {
+ File mainIsolate = new File(filePath);
+ mainIsolate.writeAsStringSync('''
+ library spawn_tests;
+
+ import \'dart:isolate\';
+
+ void main() async {
+ const String debugName = \'spawnedIsolate\';
+ final exitPort = ReceivePort();
+ final port = new ReceivePort();
+ port.listen((msg) {
+ print(msg);
+ port.close();
+ });
+
+ final isolate = await Isolate.spawnUri(
+ Uri.parse(\'$uri\'),
+ [\'$expected\'],
+ port.sendPort,
+ paused: false,
+ debugName: debugName,
+ onExit: exitPort.sendPort);
+
+ // Explicitly await spawned isolate exit to enforce main isolate not
+ // completing (and the stand-alone runtime exiting) before the spawned
+ // isolate is done.
+ await exitPort.first;
+ }
+ ''');
+ var exec = Platform.resolvedExecutable;
+ var args = <String>[];
+ args.add(mainIsolate.path);
+ var result = Process.runSync(exec, args);
+ expect(result.stdout.contains('$expected'), true);
+}
+
+void main() {
+ // Create temporary directory.
+ var tmpDir = Directory.systemTemp.createTempSync();
+ var tmpDirPath = tmpDir.path;
+
+ // Generate code for an isolate to run without any package specification.
+ File noPackageIsolate = new File("$tmpDirPath/no_package.dart");
+ noPackageIsolate.writeAsStringSync('''
+ library SpawnUriIsolate;
+ main(List<String> args, replyTo) {
+ var data = args[0];
+ replyTo.send(data);
+ }
+ ''');
+
+ try {
+ // Isolate Spawning another Isolate without any package specification.
+ testNoPackages("$tmpDirPath/no_package_isolate.dart", noPackageIsolate.path,
+ 're: no package');
+ } finally {
+ tmpDir.deleteSync(recursive: true);
+ }
+}
diff --git a/tests/lib/isolate/spawn_uri__package_uri__test.dart b/tests/lib/isolate/spawn_uri__package_uri__test.dart
new file mode 100644
index 0000000..313a55b
--- /dev/null
+++ b/tests/lib/isolate/spawn_uri__package_uri__test.dart
@@ -0,0 +1,164 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:expect/expect.dart';
+import 'package:path/path.dart' as path;
+
+final executable = Platform.executable;
+
+main() async {
+ // Run the Dart VM with or without:
+ // --packages=<packages|package_config>
+ for (final runWithPackagesArg in const [true, false]) {
+ // Run the isolate with or without
+ // Isolate.spawnUri(..., packageConfig: <packages|package_config>)
+ print('TEST runWithPackagesArg = $runWithPackagesArg ');
+ for (final spawnWithPackageConfig in const [true, false]) {
+ print('TEST spawnWithPackageConfig = $spawnWithPackageConfig ');
+ await runDotPackagesTest(runWithPackagesArg, spawnWithPackageConfig);
+ for (final optionalPackageUri in const [true, false]) {
+ print('TEST optionalPackageUri = $optionalPackageUri');
+ await runPackageConfigTest(
+ runWithPackagesArg, spawnWithPackageConfig, optionalPackageUri);
+ }
+ }
+ }
+}
+
+Future runPackageConfigTest(
+ bool withPackagesArg, bool spawnWithArg, bool optionalPackageUri) async {
+ await withApplicationDirAndDotDartToolPackageConfig(
+ (String tempDir, String packageJson, String mainFile) async {
+ final args = [if (withPackagesArg) '--packages=$packageJson', mainFile];
+ await run(executable, args);
+ }, spawnWithArg, optionalPackageUri);
+}
+
+Future runDotPackagesTest(bool withPackagesArg, bool spawnWithArg) async {
+ await withApplicationDirAndDotPackages(
+ (String tempDir, String dotPackagesFile, String mainFile) async {
+ final args = [
+ if (withPackagesArg) '--packages=$dotPackagesFile',
+ mainFile,
+ ];
+ await run(executable, args);
+ }, spawnWithArg);
+}
+
+Future withApplicationDirAndDotPackages(
+ Future fn(String tempDir, String packagesDir, String mainFile),
+ bool spawnWithArg) async {
+ await withTempDir((String tempDir) async {
+ // Setup ".packages"
+ final dotPackagesFile =
+ path.join(tempDir, spawnWithArg ? 'baz.packages' : '.packages');
+ await File(dotPackagesFile).writeAsString(buildDotPackages('foo'));
+
+ final mainFile = path.join(tempDir, 'main.dart');
+ final childIsolateFile = path.join(tempDir, 'child_isolate.dart');
+ final importUri = 'package:foo/child_isolate.dart';
+ await File(childIsolateFile).writeAsString(buildChildIsolate());
+ await File(mainFile).writeAsString(
+ buildMainIsolate(importUri, spawnWithArg ? dotPackagesFile : null));
+
+ await fn(tempDir, dotPackagesFile, mainFile);
+ });
+}
+
+Future withApplicationDirAndDotDartToolPackageConfig(
+ Future fn(String tempDir, String packageJson, String mainFile),
+ bool spawnWithArg,
+ bool optionalPackageUri) async {
+ await withTempDir((String tempDir) async {
+ // Setup ".dart_tool/package_config.json"
+ final dotDartToolDir = path.join(tempDir, '.dart_tool');
+ await Directory(dotDartToolDir).create();
+ final packageConfigJsonFile = path.join(
+ dotDartToolDir, spawnWithArg ? 'baz.packages' : 'package_config.json');
+ await File(packageConfigJsonFile)
+ .writeAsString(buildPackageConfig('foo', optionalPackageUri));
+
+ // Setup actual application
+ final mainFile = path.join(tempDir, 'main.dart');
+ final childIsolateFile = path.join(tempDir, 'child_isolate.dart');
+ final importUri = 'package:foo/child_isolate.dart';
+ await File(childIsolateFile).writeAsString(buildChildIsolate());
+ await File(mainFile).writeAsString(buildMainIsolate(
+ importUri, spawnWithArg ? packageConfigJsonFile : null));
+
+ await fn(tempDir, packageConfigJsonFile, mainFile);
+ });
+}
+
+Future withTempDir(Future fn(String dir)) async {
+ final dir = await Directory.systemTemp.createTemp('spawn_uri');
+ try {
+ await fn(dir.absolute.path);
+ } finally {
+ await dir.delete(recursive: true);
+ }
+}
+
+Future<ProcessResult> run(String executable, List<String> args,
+ {String? cwd}) async {
+ print('Running $executable ${args.join(' ')}');
+ final String workingDirectory = cwd ?? Directory.current.absolute.path;
+ final result = await Process.run(executable, ['--trace-loading', ...args],
+ workingDirectory: workingDirectory);
+ print('exitCode:\n${result.exitCode}');
+ print('stdout:\n${result.stdout}');
+ print('stdout:\n${result.stderr}');
+ Expect.equals(0, result.exitCode);
+ return result;
+}
+
+String buildDotPackages(String packageName) => '$packageName:.';
+
+String buildPackageConfig(String packageName, bool optionalPackageUri) => '''
+{
+ "configVersion": 2,
+ "packages": [
+ {
+ "name": "$packageName",
+ "rootUri": "../"
+ ${optionalPackageUri ? ', "packageUri": "./"' : ''}
+ }
+ ]
+}
+''';
+
+String buildChildIsolate() => '''
+ import 'dart:isolate';
+
+ main(List<String> args, SendPort message) {
+ message.send('child isolate is done');
+ }
+''';
+
+String buildMainIsolate(String spawnUri, String? packageConfigUri) => '''
+ import 'dart:isolate';
+ import 'dart:io' as io;
+
+ main(List<String> args) async {
+ io.exitCode = 1;
+
+ final rp = ReceivePort();
+ final uri = Uri.parse('$spawnUri');
+ final isolateArgs = <String>['a'];
+ await Isolate.spawnUri(
+ uri,
+ isolateArgs,
+ rp.sendPort,
+ packageConfig: ${packageConfigUri != null ? 'Uri.file(r"$packageConfigUri")' : 'null'});
+ final childIsolateMessage = await rp.first;
+ if (childIsolateMessage != 'child isolate is done') {
+ throw 'Did not receive correct message from child isolate.';
+ }
+
+ // Test was successful.
+ io.exitCode = 0;
+ }
+''';
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index 432516a..4523ec5 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -24,6 +24,9 @@
html/indexeddb_3_test: Skip # Times out 1 out of 10.
html/worker_api_test: Skip # Issue 13221
+[ $runtime != vm ]
+isolate/spawn_uri__package_uri__test: SkipByDesign # This test uses Isolate.spawnUri and only works in JIT mode.
+
[ $system == windows ]
html/xhr_test/xhr: Skip # Times out. Issue 21527
@@ -91,6 +94,7 @@
isolate/mint_maker_test: Skip # Isolate.spawnUri
isolate/nested_spawn2_test: Skip # Isolate.spawnUri
isolate/nested_spawn_test: Skip # Isolate.spawnUri
+isolate/no_package_test: Skip # Isolate.spawnUri
isolate/raw_port_test: Skip # Isolate.spawnUri
isolate/request_reply_test: Skip # Isolate.spawnUri
isolate/spawn_function_custom_class_test: Skip # Isolate.spawnUri
diff --git a/tests/lib/lib_vm.status b/tests/lib/lib_vm.status
index 92cc427..9465a91 100644
--- a/tests/lib/lib_vm.status
+++ b/tests/lib/lib_vm.status
@@ -152,6 +152,7 @@
isolate/spawn_function_custom_class_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
isolate/spawn_function_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
isolate/spawn_generic_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
+isolate/spawn_uri__package_uri__test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
isolate/spawn_uri_exported_main_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
isolate/spawn_uri_missing_from_isolate_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
isolate/spawn_uri_missing_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
diff --git a/tests/lib_2/isolate/spawn_uri__package_uri__test.dart b/tests/lib_2/isolate/spawn_uri__package_uri__test.dart
new file mode 100644
index 0000000..f34eb46
--- /dev/null
+++ b/tests/lib_2/isolate/spawn_uri__package_uri__test.dart
@@ -0,0 +1,164 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:expect/expect.dart';
+import 'package:path/path.dart' as path;
+
+final executable = Platform.executable;
+
+main() async {
+ // Run the Dart VM with or without:
+ // --packages=<packages|package_config>
+ for (final runWithPackagesArg in const [true, false]) {
+ // Run the isolate with or without
+ // Isolate.spawnUri(..., packageConfig: <packages|package_config>)
+ print('TEST runWithPackagesArg = $runWithPackagesArg ');
+ for (final spawnWithPackageConfig in const [true, false]) {
+ print('TEST spawnWithPackageConfig = $spawnWithPackageConfig ');
+ await runDotPackagesTest(runWithPackagesArg, spawnWithPackageConfig);
+ for (final optionalPackageUri in const [true, false]) {
+ print('TEST optionalPackageUri = $optionalPackageUri');
+ await runPackageConfigTest(
+ runWithPackagesArg, spawnWithPackageConfig, optionalPackageUri);
+ }
+ }
+ }
+}
+
+Future runPackageConfigTest(
+ bool withPackagesArg, bool spawnWithArg, bool optionalPackageUri) async {
+ await withApplicationDirAndDotDartToolPackageConfig(
+ (String tempDir, String packageJson, String mainFile) async {
+ final args = [if (withPackagesArg) '--packages=$packageJson', mainFile];
+ await run(executable, args);
+ }, spawnWithArg, optionalPackageUri);
+}
+
+Future runDotPackagesTest(bool withPackagesArg, bool spawnWithArg) async {
+ await withApplicationDirAndDotPackages(
+ (String tempDir, String dotPackagesFile, String mainFile) async {
+ final args = [
+ if (withPackagesArg) '--packages=$dotPackagesFile',
+ mainFile,
+ ];
+ await run(executable, args);
+ }, spawnWithArg);
+}
+
+Future withApplicationDirAndDotPackages(
+ Future fn(String tempDir, String packagesDir, String mainFile),
+ bool spawnWithArg) async {
+ await withTempDir((String tempDir) async {
+ // Setup ".packages"
+ final dotPackagesFile =
+ path.join(tempDir, spawnWithArg ? 'baz.packages' : '.packages');
+ await File(dotPackagesFile).writeAsString(buildDotPackages('foo'));
+
+ final mainFile = path.join(tempDir, 'main.dart');
+ final childIsolateFile = path.join(tempDir, 'child_isolate.dart');
+ final importUri = 'package:foo/child_isolate.dart';
+ await File(childIsolateFile).writeAsString(buildChildIsolate());
+ await File(mainFile).writeAsString(
+ buildMainIsolate(importUri, spawnWithArg ? dotPackagesFile : null));
+
+ await fn(tempDir, dotPackagesFile, mainFile);
+ });
+}
+
+Future withApplicationDirAndDotDartToolPackageConfig(
+ Future fn(String tempDir, String packageJson, String mainFile),
+ bool spawnWithArg,
+ bool optionalPackageUri) async {
+ await withTempDir((String tempDir) async {
+ // Setup ".dart_tool/package_config.json"
+ final dotDartToolDir = path.join(tempDir, '.dart_tool');
+ await Directory(dotDartToolDir).create();
+ final packageConfigJsonFile = path.join(
+ dotDartToolDir, spawnWithArg ? 'baz.packages' : 'package_config.json');
+ await File(packageConfigJsonFile)
+ .writeAsString(buildPackageConfig('foo', optionalPackageUri));
+
+ // Setup actual application
+ final mainFile = path.join(tempDir, 'main.dart');
+ final childIsolateFile = path.join(tempDir, 'child_isolate.dart');
+ final importUri = 'package:foo/child_isolate.dart';
+ await File(childIsolateFile).writeAsString(buildChildIsolate());
+ await File(mainFile).writeAsString(buildMainIsolate(
+ importUri, spawnWithArg ? packageConfigJsonFile : null));
+
+ await fn(tempDir, packageConfigJsonFile, mainFile);
+ });
+}
+
+Future withTempDir(Future fn(String dir)) async {
+ final dir = await Directory.systemTemp.createTemp('spawn_uri');
+ try {
+ await fn(dir.absolute.path);
+ } finally {
+ await dir.delete(recursive: true);
+ }
+}
+
+Future<ProcessResult> run(String executable, List<String> args,
+ {String cwd}) async {
+ print('Running $executable ${args.join(' ')}');
+ final String workingDirectory = cwd ?? Directory.current.absolute.path;
+ final result = await Process.run(executable, ['--trace-loading', ...args],
+ workingDirectory: workingDirectory);
+ print('exitCode:\n${result.exitCode}');
+ print('stdout:\n${result.stdout}');
+ print('stdout:\n${result.stderr}');
+ Expect.equals(0, result.exitCode);
+ return result;
+}
+
+String buildDotPackages(String packageName) => '$packageName:.';
+
+String buildPackageConfig(String packageName, bool optionalPackageUri) => '''
+{
+ "configVersion": 2,
+ "packages": [
+ {
+ "name": "$packageName",
+ "rootUri": "../"
+ ${optionalPackageUri ? ', "packageUri": "./"' : ''}
+ }
+ ]
+}
+''';
+
+String buildChildIsolate() => '''
+ import 'dart:isolate';
+
+ main(List<String> args, SendPort message) {
+ message.send('child isolate is done');
+ }
+''';
+
+String buildMainIsolate(String spawnUri, String packageConfigUri) => '''
+ import 'dart:isolate';
+ import 'dart:io' as io;
+
+ main(List<String> args) async {
+ io.exitCode = 1;
+
+ final rp = ReceivePort();
+ final uri = Uri.parse('$spawnUri');
+ final isolateArgs = <String>['a'];
+ await Isolate.spawnUri(
+ uri,
+ isolateArgs,
+ rp.sendPort,
+ packageConfig: ${packageConfigUri != null ? 'Uri.file(r"$packageConfigUri")' : 'null'});
+ final childIsolateMessage = await rp.first;
+ if (childIsolateMessage != 'child isolate is done') {
+ throw 'Did not receive correct message from child isolate.';
+ }
+
+ // Test was successful.
+ io.exitCode = 0;
+ }
+''';
diff --git a/tests/lib_2/lib_2.status b/tests/lib_2/lib_2.status
index 432516a..855ab43 100644
--- a/tests/lib_2/lib_2.status
+++ b/tests/lib_2/lib_2.status
@@ -24,6 +24,9 @@
html/indexeddb_3_test: Skip # Times out 1 out of 10.
html/worker_api_test: Skip # Issue 13221
+[ $runtime != vm ]
+isolate/spawn_uri__package_uri__test: SkipByDesign # This test uses Isolate.spawnUri and only works in JIT mode.
+
[ $system == windows ]
html/xhr_test/xhr: Skip # Times out. Issue 21527
diff --git a/tests/lib_2/lib_2_vm.status b/tests/lib_2/lib_2_vm.status
index 78b9986..77c441a 100644
--- a/tests/lib_2/lib_2_vm.status
+++ b/tests/lib_2/lib_2_vm.status
@@ -137,6 +137,7 @@
isolate/spawn_function_custom_class_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
isolate/spawn_function_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
isolate/spawn_generic_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
+isolate/spawn_uri__package_uri__test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
isolate/spawn_uri_exported_main_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
isolate/spawn_uri_missing_from_isolate_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
isolate/spawn_uri_missing_test: Skip # https://dartbug.com/36097: Ongoing concurrency work.
diff --git a/tests/standalone/io/internet_address_test.dart b/tests/standalone/io/internet_address_test.dart
index 493957e..d4d6a06 100644
--- a/tests/standalone/io/internet_address_test.dart
+++ b/tests/standalone/io/internet_address_test.dart
@@ -74,6 +74,55 @@
Expect.throwsArgumentError(() => new InternetAddress("::FFFF::1"));
}
+void testTryParse() {
+ var loopback4 = InternetAddress.tryParse("127.0.0.1")!;
+ Expect.equals(InternetAddressType.IPv4, loopback4.type);
+ Expect.equals("127.0.0.1", loopback4.host);
+ Expect.equals("127.0.0.1", loopback4.address);
+ Expect.isFalse(loopback4.isMulticast);
+
+ var loopback6 = InternetAddress.tryParse("::1")!;
+ Expect.equals(InternetAddressType.IPv6, loopback6.type);
+ Expect.equals("::1", loopback6.host);
+ Expect.equals("::1", loopback6.address);
+ Expect.isFalse(loopback6.isMulticast);
+
+ var ip4 = InternetAddress.tryParse("10.20.30.40")!;
+ Expect.equals(InternetAddressType.IPv4, ip4.type);
+ Expect.equals("10.20.30.40", ip4.host);
+ Expect.equals("10.20.30.40", ip4.address);
+ Expect.isFalse(ip4.isMulticast);
+
+ var ip6 = InternetAddress.tryParse("10:20::30:40")!;
+ Expect.equals(InternetAddressType.IPv6, ip6.type);
+ Expect.equals("10:20::30:40", ip6.host);
+ Expect.equals("10:20::30:40", ip6.address);
+ Expect.isFalse(ip6.isMulticast);
+
+ var multicast4 = InternetAddress.tryParse("224.1.2.3")!;
+ Expect.equals(InternetAddressType.IPv4, multicast4.type);
+ Expect.isTrue(multicast4.isMulticast);
+
+ var multicast6 = InternetAddress.tryParse("FF00::1:2:3")!;
+ Expect.equals(InternetAddressType.IPv6, multicast6.type);
+ Expect.isTrue(multicast6.isMulticast);
+
+ var lowercase = InternetAddress.tryParse("ff00::1:2:3")!;
+ Expect.equals(InternetAddressType.IPv6, lowercase.type);
+ Expect.equals("ff00::1:2:3", lowercase.host);
+ Expect.equals("ff00::1:2:3", lowercase.address);
+
+ Expect.isNull(InternetAddress.tryParse("1.2.3"));
+ Expect.isNull(InternetAddress.tryParse("1.2.3.4.5"));
+ Expect.isNull(InternetAddress.tryParse("192.168.256.0"));
+ Expect.isNull(InternetAddress.tryParse("192.168.999.0"));
+ Expect.isNull(InternetAddress.tryParse("1.-2.3.4"));
+ Expect.isNull(InternetAddress.tryParse(""));
+ Expect.isNull(InternetAddress.tryParse("FFFG::0"));
+ Expect.isNull(InternetAddress.tryParse("FFF@::0"));
+ Expect.isNull(InternetAddress.tryParse("::FFFF::1"));
+}
+
void testEquality() {
Expect.equals(
new InternetAddress("127.0.0.1"), new InternetAddress("127.0.0.1"));
@@ -163,6 +212,7 @@
void main() {
testDefaultAddresses();
testConstructor();
+ testTryParse();
testEquality();
testLookup();
testReverseLookup();
diff --git a/tests/standalone_2/io/internet_address_test.dart b/tests/standalone_2/io/internet_address_test.dart
index d35e91c..6d2dd54 100644
--- a/tests/standalone_2/io/internet_address_test.dart
+++ b/tests/standalone_2/io/internet_address_test.dart
@@ -74,6 +74,55 @@
Expect.throwsArgumentError(() => new InternetAddress("::FFFF::1"));
}
+void testTryParse() {
+ var loopback4 = InternetAddress.tryParse("127.0.0.1");
+ Expect.equals(InternetAddressType.IPv4, loopback4.type);
+ Expect.equals("127.0.0.1", loopback4.host);
+ Expect.equals("127.0.0.1", loopback4.address);
+ Expect.isFalse(loopback4.isMulticast);
+
+ var loopback6 = InternetAddress.tryParse("::1");
+ Expect.equals(InternetAddressType.IPv6, loopback6.type);
+ Expect.equals("::1", loopback6.host);
+ Expect.equals("::1", loopback6.address);
+ Expect.isFalse(loopback6.isMulticast);
+
+ var ip4 = InternetAddress.tryParse("10.20.30.40");
+ Expect.equals(InternetAddressType.IPv4, ip4.type);
+ Expect.equals("10.20.30.40", ip4.host);
+ Expect.equals("10.20.30.40", ip4.address);
+ Expect.isFalse(ip4.isMulticast);
+
+ var ip6 = InternetAddress.tryParse("10:20::30:40");
+ Expect.equals(InternetAddressType.IPv6, ip6.type);
+ Expect.equals("10:20::30:40", ip6.host);
+ Expect.equals("10:20::30:40", ip6.address);
+ Expect.isFalse(ip6.isMulticast);
+
+ var multicast4 = InternetAddress.tryParse("224.1.2.3");
+ Expect.equals(InternetAddressType.IPv4, multicast4.type);
+ Expect.isTrue(multicast4.isMulticast);
+
+ var multicast6 = InternetAddress.tryParse("FF00::1:2:3");
+ Expect.equals(InternetAddressType.IPv6, multicast6.type);
+ Expect.isTrue(multicast6.isMulticast);
+
+ var lowercase = InternetAddress.tryParse("ff00::1:2:3");
+ Expect.equals(InternetAddressType.IPv6, lowercase.type);
+ Expect.equals("ff00::1:2:3", lowercase.host);
+ Expect.equals("ff00::1:2:3", lowercase.address);
+
+ Expect.isNull(InternetAddress.tryParse("1.2.3"));
+ Expect.isNull(InternetAddress.tryParse("1.2.3.4.5"));
+ Expect.isNull(InternetAddress.tryParse("192.168.256.0"));
+ Expect.isNull(InternetAddress.tryParse("192.168.999.0"));
+ Expect.isNull(InternetAddress.tryParse("1.-2.3.4"));
+ Expect.isNull(InternetAddress.tryParse(""));
+ Expect.isNull(InternetAddress.tryParse("FFFG::0"));
+ Expect.isNull(InternetAddress.tryParse("FFF@::0"));
+ Expect.isNull(InternetAddress.tryParse("::FFFF::1"));
+}
+
void testEquality() {
Expect.equals(
new InternetAddress("127.0.0.1"), new InternetAddress("127.0.0.1"));
@@ -162,6 +211,7 @@
void main() {
testDefaultAddresses();
testConstructor();
+ testTryParse();
testEquality();
testLookup();
testReverseLookup();
diff --git a/tools/VERSION b/tools/VERSION
index 2aa401e..1de73ea 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -33,7 +33,7 @@
MAJOR 2
MINOR 9
PATCH 0
-PRERELEASE 5
+PRERELEASE 6
PRERELEASE_PATCH 0
ABI_VERSION 32
OLDEST_SUPPORTED_ABI_VERSION 32
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index 32fbbf1..92dd685 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -40,6 +40,12 @@
"tests/co19_2/co19_2-dartdevc.status",
"tests/co19_2/co19_2-kernel.status",
"tests/co19_2/co19_2-runtime.status",
+ "tests/co19/co19-analyzer.status",
+ "tests/co19/co19-co19.status",
+ "tests/co19/co19-dart2js.status",
+ "tests/co19/co19-dartdevc.status",
+ "tests/co19/co19-kernel.status",
+ "tests/co19/co19-runtime.status",
"tests/compiler/",
"tests/corelib_2/",
"tests/dart/",
@@ -74,6 +80,12 @@
"sdk_nnbd/",
"tests/.dart_tool/package_config.json",
"tests/angular/",
+ "tests/co19/co19-analyzer.status",
+ "tests/co19/co19-co19.status",
+ "tests/co19/co19-dart2js.status",
+ "tests/co19/co19-dartdevc.status",
+ "tests/co19/co19-kernel.status",
+ "tests/co19/co19-runtime.status",
"tests/co19_2/co19_2-analyzer.status",
"tests/co19_2/co19_2-co19.status",
"tests/co19_2/co19_2-dart2js.status",
@@ -120,6 +132,12 @@
"sdk/",
"tests/.dart_tool/package_config.json",
"tests/angular/",
+ "tests/co19/co19-analyzer.status",
+ "tests/co19/co19-co19.status",
+ "tests/co19/co19-dart2js.status",
+ "tests/co19/co19-dartdevc.status",
+ "tests/co19/co19-kernel.status",
+ "tests/co19/co19-runtime.status",
"tests/co19_2/co19_2-analyzer.status",
"tests/co19_2/co19_2-co19.status",
"tests/co19_2/co19_2-dart2js.status",
@@ -163,6 +181,12 @@
"sdk_nnbd/",
"tests/.dart_tool/package_config.json",
"tests/angular/",
+ "tests/co19/co19-analyzer.status",
+ "tests/co19/co19-co19.status",
+ "tests/co19/co19-dart2js.status",
+ "tests/co19/co19-dartdevc.status",
+ "tests/co19/co19-kernel.status",
+ "tests/co19/co19-runtime.status",
"tests/co19_2/co19_2-analyzer.status",
"tests/co19_2/co19_2-co19.status",
"tests/co19_2/co19_2-dart2js.status",
@@ -205,6 +229,12 @@
"sdk_nnbd/",
"tests/.dart_tool/package_config.json",
"tests/angular/",
+ "tests/co19/co19-analyzer.status",
+ "tests/co19/co19-co19.status",
+ "tests/co19/co19-dart2js.status",
+ "tests/co19/co19-dartdevc.status",
+ "tests/co19/co19-kernel.status",
+ "tests/co19/co19-runtime.status",
"tests/co19_2/co19_2-analyzer.status",
"tests/co19_2/co19_2-co19.status",
"tests/co19_2/co19_2-dart2js.status",
@@ -307,6 +337,12 @@
"third_party/pkg_tested/",
"tests/.dart_tool/package_config.json",
"tests/angular/",
+ "tests/co19/co19-analyzer.status",
+ "tests/co19/co19-co19.status",
+ "tests/co19/co19-dart2js.status",
+ "tests/co19/co19-dartdevc.status",
+ "tests/co19/co19-kernel.status",
+ "tests/co19/co19-runtime.status",
"tests/co19_2/co19_2-analyzer.status",
"tests/co19_2/co19_2-co19.status",
"tests/co19_2/co19_2-dart2js.status",
@@ -393,6 +429,12 @@
"third_party/pkg_tested/",
"tests/.dart_tool/package_config.json",
"tests/angular/",
+ "tests/co19/co19-analyzer.status",
+ "tests/co19/co19-co19.status",
+ "tests/co19/co19-dart2js.status",
+ "tests/co19/co19-dartdevc.status",
+ "tests/co19/co19-kernel.status",
+ "tests/co19/co19-runtime.status",
"tests/co19_2/co19_2-analyzer.status",
"tests/co19_2/co19_2-co19.status",
"tests/co19_2/co19_2-dart2js.status",
@@ -785,6 +827,11 @@
}
},
"dartk-(linux|mac|win)-(debug|product|release)-(ia32|x64)": {},
+ "dartk-linux-debug-(ia32|x64)-canary": {
+ "options": {
+ "builder-tag": "canary"
+ }
+ },
"dartkp-weak-asserts-(linux|mac)-(debug|product|release)-x64": {
"options": {
"enable-experiment": [
@@ -1266,14 +1313,14 @@
{
"name": "vm ia32 tests",
"arguments": [
- "-ndartk-linux-debug-ia32",
+ "-ndartk-linux-debug-ia32-canary",
"vm"
]
},
{
"name": "vm x64 tests",
"arguments": [
- "-ndartk-linux-debug-x64",
+ "-ndartk-linux-debug-x64-canary",
"vm"
]
}
@@ -1423,6 +1470,7 @@
"ffi",
"language",
"lib",
+ "co19/LanguageFeatures/nnbd",
"standalone/io"
]
},
@@ -1434,6 +1482,7 @@
"ffi",
"language",
"lib",
+ "co19/LanguageFeatures/nnbd",
"standalone/io"
]
}
@@ -1589,7 +1638,7 @@
"vm-kernel-asan-linux-release-ia32",
"vm-kernel-asan-linux-release-x64",
"vm-kernel-lsan-linux-release-ia32",
- "vm-kernel-lsan-linux-release-x64",
+ "vm-kernel-lsan-linux-release-x64",
"vm-kernel-msan-linux-release-x64",
"vm-kernel-ubsan-linux-release-ia32",
"vm-kernel-ubsan-linux-release-x64"
@@ -1786,6 +1835,7 @@
"ffi",
"language",
"lib",
+ "co19/LanguageFeatures/nnbd",
"standalone/io"
]
},
@@ -1797,6 +1847,7 @@
"ffi",
"language",
"lib",
+ "co19/LanguageFeatures/nnbd",
"standalone/io"
]
}
diff --git a/tools/dom/templates/html/impl/impl_DocumentFragment.darttemplate b/tools/dom/templates/html/impl/impl_DocumentFragment.darttemplate
index d2b2c9d..22b74d9 100644
--- a/tools/dom/templates/html/impl/impl_DocumentFragment.darttemplate
+++ b/tools/dom/templates/html/impl/impl_DocumentFragment.darttemplate
@@ -7,7 +7,7 @@
$(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS {
factory $CLASSNAME() => document.createDocumentFragment();
- factory $CLASSNAME.html(String html,
+ factory $CLASSNAME.html(String$NULLABLE html,
{NodeValidator$NULLABLE validator,
NodeTreeSanitizer$NULLABLE treeSanitizer}) {
@@ -15,7 +15,7 @@
validator: validator, treeSanitizer: treeSanitizer);
}
- factory $CLASSNAME.svg(String svgContent,
+ factory $CLASSNAME.svg(String$NULLABLE svgContent,
{NodeValidator$NULLABLE validator,
NodeTreeSanitizer$NULLABLE treeSanitizer}) {
@@ -66,11 +66,11 @@
return e.innerHtml;
}
- set innerHtml(String value) {
+ set innerHtml(String$NULLABLE value) {
this.setInnerHtml(value);
}
- void setInnerHtml(String html,
+ void setInnerHtml(String$NULLABLE html,
{NodeValidator$NULLABLE validator,
NodeTreeSanitizer$NULLABLE treeSanitizer}) {
diff --git a/tools/dom/templates/html/impl/impl_Element.darttemplate b/tools/dom/templates/html/impl/impl_Element.darttemplate
index 4ad8736..6523947 100644
--- a/tools/dom/templates/html/impl/impl_Element.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Element.darttemplate
@@ -350,7 +350,7 @@
* * [NodeValidator]
*
*/
- factory Element.html(String html,
+ factory Element.html(String$NULLABLE html,
{NodeValidator$NULLABLE validator,
NodeTreeSanitizer$NULLABLE treeSanitizer}) {
var fragment = document.body$NULLASSERT.createFragment(html,
@@ -1324,7 +1324,7 @@
* * [NodeValidator]
* * [NodeTreeSanitizer]
*/
- DocumentFragment createFragment(String html,
+ DocumentFragment createFragment(String$NULLABLE html,
{NodeValidator$NULLABLE validator,
NodeTreeSanitizer$NULLABLE treeSanitizer}) {
if (treeSanitizer == null) {
@@ -1374,7 +1374,7 @@
if (Range.supportsCreateContextualFragment &&
_canBeUsedToCreateContextualFragment) {
_parseRange$NULLASSERT.selectNodeContents(contextElement);
- fragment = _parseRange$NULLASSERT.createContextualFragment(html);
+ fragment = _parseRange$NULLASSERT.createContextualFragment(html$NULLASSERT);
} else {
contextElement._innerHtml = html;
@@ -1450,8 +1450,8 @@
if (treeSanitizer is _TrustedHtmlTreeSanitizer) {
_innerHtml = html;
} else {
- append(createFragment(
- html$NULLASSERT, validator: validator, treeSanitizer: treeSanitizer));
+ append(createFragment(html, validator: validator,
+ treeSanitizer: treeSanitizer));
}
}
String get innerHtml => _innerHtml;
diff --git a/tools/dom/templates/html/impl/impl_HTMLTableElement.darttemplate b/tools/dom/templates/html/impl/impl_HTMLTableElement.darttemplate
index d53310c..7add9d0 100644
--- a/tools/dom/templates/html/impl/impl_HTMLTableElement.darttemplate
+++ b/tools/dom/templates/html/impl/impl_HTMLTableElement.darttemplate
@@ -34,7 +34,7 @@
@JSName('createTBody')
TableSectionElement _nativeCreateTBody() native;
- DocumentFragment createFragment(String html,
+ DocumentFragment createFragment(String$NULLABLE html,
{NodeValidator$NULLABLE validator,
NodeTreeSanitizer$NULLABLE treeSanitizer}) {
if (Range.supportsCreateContextualFragment) {
diff --git a/tools/dom/templates/html/impl/impl_HTMLTableRowElement.darttemplate b/tools/dom/templates/html/impl/impl_HTMLTableRowElement.darttemplate
index 5d689c7..7ac5c5c 100644
--- a/tools/dom/templates/html/impl/impl_HTMLTableRowElement.darttemplate
+++ b/tools/dom/templates/html/impl/impl_HTMLTableRowElement.darttemplate
@@ -16,7 +16,7 @@
TableCellElement insertCell(int index) =>
_insertCell(index) $#NULLSAFECAST(as TableCellElement);
- DocumentFragment createFragment(String html,
+ DocumentFragment createFragment(String$NULLABLE html,
{NodeValidator$NULLABLE validator,
NodeTreeSanitizer$NULLABLE treeSanitizer}) {
if (Range.supportsCreateContextualFragment) {
diff --git a/tools/dom/templates/html/impl/impl_HTMLTableSectionElement.darttemplate b/tools/dom/templates/html/impl/impl_HTMLTableSectionElement.darttemplate
index 0b3b665..6bdd040 100644
--- a/tools/dom/templates/html/impl/impl_HTMLTableSectionElement.darttemplate
+++ b/tools/dom/templates/html/impl/impl_HTMLTableSectionElement.darttemplate
@@ -15,7 +15,7 @@
TableRowElement insertRow(int index) => _insertRow(index) $#NULLSAFECAST(as TableRowElement);
- DocumentFragment createFragment(String html,
+ DocumentFragment createFragment(String$NULLABLE html,
{NodeValidator$NULLABLE validator,
NodeTreeSanitizer$NULLABLE treeSanitizer}) {
if (Range.supportsCreateContextualFragment) {
diff --git a/tools/dom/templates/html/impl/impl_HTMLTemplateElement.darttemplate b/tools/dom/templates/html/impl/impl_HTMLTemplateElement.darttemplate
index 7981962..d030d27 100644
--- a/tools/dom/templates/html/impl/impl_HTMLTemplateElement.darttemplate
+++ b/tools/dom/templates/html/impl/impl_HTMLTemplateElement.darttemplate
@@ -21,8 +21,8 @@
NodeTreeSanitizer$NULLABLE treeSanitizer}) {
text = null;
content.nodes.clear();
- var fragment = createFragment(
- html$NULLASSERT, validator: validator, treeSanitizer: treeSanitizer);
+ var fragment = createFragment(html, validator: validator,
+ treeSanitizer: treeSanitizer);
content.append(fragment);
}
diff --git a/tools/dom/templates/html/impl/impl_SVGElement.darttemplate b/tools/dom/templates/html/impl/impl_SVGElement.darttemplate
index a92eb50..ca93287 100644
--- a/tools/dom/templates/html/impl/impl_SVGElement.darttemplate
+++ b/tools/dom/templates/html/impl/impl_SVGElement.darttemplate
@@ -86,7 +86,7 @@
this.setInnerHtml(value);
}
- DocumentFragment createFragment(String svg,
+ DocumentFragment createFragment(String$NULLABLE svg,
{NodeValidator$NULLABLE validator,
NodeTreeSanitizer$NULLABLE treeSanitizer}) {
diff --git a/tools/generate_package_config.dart b/tools/generate_package_config.dart
index e0ddfb8..1833b60 100755
--- a/tools/generate_package_config.dart
+++ b/tools/generate_package_config.dart
@@ -74,6 +74,12 @@
var version = pubspecLanguageVersion(packageDir);
var hasLibDirectory = Directory(p.join(packageDir, 'lib')).existsSync();
+ // TODO(rnystrom): Currently, the pre-built SDK does not allow language
+ // version 2.9.0. Until that's fixed, if we see that version, just write
+ // no version at all so that implementations use the current language
+ // version.
+ if (version.toString() == '2.9.0') version = null;
+
yield {
'name': p.basename(packageDir),
'rootUri': p.relative(packageDir, from: p.dirname(configFilePath)),
diff --git a/tools/run_abi_tests.py b/tools/run_abi_tests.py
index 83c26e6..cecf86a 100644
--- a/tools/run_abi_tests.py
+++ b/tools/run_abi_tests.py
@@ -163,7 +163,7 @@
# Create a log entry for a test that has diffs. Concatenate all the log records
# and include which tests failed.
-def makeLog(diffs, results, logRecords):
+def makeLog(diffs, results, logRecords, configuration_name):
result = pickOne(results)
logs = ["%s: %s" % (str(v), l['log']) for v, l in logRecords.items()]
return {
@@ -190,7 +190,9 @@
if diffs:
logRecords = allLogs[name] if name in allLogs else []
logFile.write(
- json.dumps(makeLog(diffs, results, logRecords)) + '\n')
+ json.dumps(
+ makeLog(diffs, results, logRecords, flags.
+ configuration_name)) + '\n')
print('Log files emitted to %s and %s' % (resultFileName, logFileName))
diff --git a/tools/sdks/update.sh b/tools/sdks/update.sh
index 6f1cc4e..dc96ef1 100755
--- a/tools/sdks/update.sh
+++ b/tools/sdks/update.sh
@@ -9,8 +9,8 @@
fi
case "$1" in
-*-dev.*.0) channel="dev";;
-*-dev.*) channel="beta";;
+*-*.0.dev) channel="dev";;
+*-*.*.beta) channel="beta";;
*) channel="stable";;
esac
@@ -83,3 +83,5 @@
rm -rf sdk
popd
+
+gclient setdep --var="sdk_tag=version:$1"